摘要:最近在上看到一篇关于变量提升的文章,原文在此。对于刚入门的开发者时常难以理解变量方法提升的独特行为。接下来我们要谈论,,声明,那么先了解变量提升就显得更为重要了。在进入作用域和不能访问的这段时间,我们称为暂时性死区。
最近在Medium上看到一篇关于“变量提升”的文章,原文在此:《A guide to JavaScript variable hoisting with let and const》。为了培养自己看英文文档习惯且看懂的需要,就翻译一下。谈不上精确,欢迎指正。
对于刚入门的JavaScript开发者时常难以理解“变量/方法”提升(hoisting)的独特行为。
接下来我们要谈论var,let,const声明,那么先了解变量提升就显得更为重要了。那就开始吧。
JavaScript引擎用“var”处理所有变量声明,不管在哪里声明,最后都会在函数作用域顶端(如果在函数内部声明)或则在全局作用域顶端(在函数外部声明)。这就是“提升”。
因此变量实际上可能在声明它之前就已经被引擎获得了。
在实际操作中看看效果..
// OUTPUT : undefined console.log(shape); var shape = square; // OUTPUT : square console.log(shape);
如果你来自C语言,你认为在第一个console.log那里就会抛出变量未定义的错误。但JavaScript解释器预感和“提升”所有变量声明到作用域顶端,并且在那进行初始化。
下面演示实际发生了什么:
//declaration getting hoisted at the top var shape; // OUTPUT : undefined console.log(shape); shape = square; // OUTPUT : square console.log(shape);
另一个例子是用函数作用域来更清楚的展示:
function getShape(condition) { // shape exists here with a value of undefined // OUTPUT : undefined console.log(shape); if (condition) { var shape = square; // some other code return shape; } else { // shape exists here with a value of undefined return false; } }
上面的例子可以看出shape声明被提升到了“getShape”函数作用域的顶端。这是因为“if/else” 不能像其他语言那样,创建局部作用域。在JavaScript里,函数作用域实际上就是局部作用域了。因此,“shape”可以在if块之外,函数作用域内任意访问,且值为“undefined”。
JavaScript的这个默认行为,既是优点,又是缺点。没有完全掌握的话,会给我们的代码带来细微且危险的bugs。
进入块级作用域!
ES6 引入了块级作用域,这让开发者对变量有了更多的控制,且让变量有灵活的生命周期。
块级声明在块级/词法作用域里面声明,他们在“{}”中被创建。
“let”语法跟“var”相似,只是用“let”标识符来替换“var”标识符进行变量声明,其作用域范围仅仅在声明的那个代码块。
let声明放在块的顶端,因此只能在那个块级作用域中访问。
举例:
function getShape(condition) { // shape doesn"t exist here // console.log(shape); ReferenceError: shape is not defined if (condition) { let shape = square; // some other code return shape; } else { // shape doesn"t exist here as well return false; } }
注意shape只存在if块中,当在if块外面访问时会抛出一个错误,而不是象我们之前用var声明那样输出“undefined”。
提示:在同一个作用域内,如果已经使用var标识符声明了变量,同时又用let标识符声明同名变量时会抛出错误。
但是,如果在let声明的变量作用域外,声明同名变量是不会报错的。(这种情况也同样适用于我们即将谈论的const声明。)
举例:
var shape = square; let shape = rectangle; // SyntaxError: Identifier "shape" has already been declared
和
var shape = square; if (condition) { // doesn"t throw an error let shape = rectangle; // more code } // No errorconst声明
const声明语法与let和var相似,生命周期与let相同,但你还要注意一些规则。
用const声明的变量将像常量看待,因此它们的值在定义后是不可以修改的。由于这样,每个const变量都必须在声明的同时进行初始化。
举例:
// valid const shape = triangle; // syntax error: missing initialization const color; // TypeError: Assignment to constant variable shape = square;
然而,这个规则在声明对象时有点不同。对象属性的值可以被修改!
const shape = { name: triangle, sides: 3 } // WORKS shape.name = square; shape.sides = 4; // SyntaxError: Invalid shorthand property initializer shape = { name: hexagon, sides: 6 }
在上面的例子中,我们可以看到shape对象属性的值可以被修改,因为我们只改变shape包含的,而不是它本身。
我们可以总结说,const可以防止整个绑定的修改,而不是绑定的值。
提示:属性可以改变。所以对于真正不可变的,请使用Immutable.js或Mori。
我们都知道,如果我们在使用let,const声明定义的变量之前就使用这些变量,会抛出ReferenceError错误。 在进入作用域和不能访问的这段时间,我们称为暂时性死区。
提示:“暂时性死区”不是ECMAScript规范里的正式定义,它只是在程序员中广为流行而已。
我个人推荐总是使用const,因为它不容易出错。我还没遇到需要使用var的情况。
作为基本规则,只在循环计数器中,或则你真的需要给变量从新赋值时用let。其他地方,用const。我已经放弃使用循环,转而选择使用filter,map,reduce等方法。你也应该如此。
后记,此作者还有一篇关于方法提升的文章,到时候在搬来。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/90355.html
摘要:函数提升在里有两种方式创建函数,通过函数声明和函数表达式。函数声明用指定的参数来定义函数。提示不要在中进行函数声明。问题输出两个都是用函数声明的函数,将被提升到的局部作用域顶端。函数本身将作为函数声明在全局范围内提升。 作者关于提升的话题,总共有两篇。(后来又有一个讨论篇),再次搬过来。水平有限,如果翻译的不准确请包涵,并去看原文。下面开始: 这是我之前的关于提升的文章,标题为《用le...
摘要:理解执行上下文和执行堆栈对于理解的其它概念如提升,范围和闭包至关重要。正确地理解执行上下文和执行堆栈将帮助你更好地使用开发应用。引擎执行位于执行堆栈顶部的方法。当调用时,为该函数创建一个新的执行上下文,并且把它推入到当前执行堆栈。 By Sukhjinder Arora | Aug 28, 2018 原文 如果你是或者你想要成为一名js开发者,那么你必须了解js程序内部的运作。理解执行...
摘要:外层作用域不报错正常输出块级作用域与函数声明规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。规定,块级作用域之中,函数声明语句的行为类似于,在块级作用域之外不可引用。同时,函数声明还会提升到所在的块级作用域的头部。 前言:最近开始看阮一峰老师的《ECMAScript 6 入门》(以下简称原...
摘要:如果是你是高级或者初级开发人员,了解它的基本概念非常重要。由于是基本类型,因此的值等于的值,并且可以认为此时与完全不同。展开运算符可用于提取数组的各个元素。函数本身返回从数组中删除的项。如果未指定结束位置,则返回数组的其余部分。 译者:前端小智 原文:hackernoon.com/12-javascri… JavaScript 是一种复杂的语言。如果是你是高级或者初级 JavaScript...
摘要:中的所有对象都来自父的构造函数。不同于数组的原型方法例如和只能被数组实例使用,对象方法直接来自构造函数,并使用对象实例作为参数。这称为静态方法。创建对象的键值对的嵌套数组。可用于确定对象是否已冻结,并返回布尔值。 原文:How To Use Object Methods in JavaScript作者:Tania Rascia译者:博轩 介绍 JavaScript 中,对象是 键/值 ...
阅读 3616·2021-11-24 10:22
阅读 3686·2021-11-22 09:34
阅读 2480·2021-11-15 11:39
阅读 1528·2021-10-14 09:42
阅读 3662·2021-10-08 10:04
阅读 1553·2019-08-30 15:52
阅读 846·2019-08-30 13:49
阅读 3015·2019-08-30 11:21