T.J*_*der 42
新款let和constES2015(又称"ES6")与古老版相比有四个主要差异var:
他们有块范围
它们没有悬挂(好吧,它们有点悬挂,但是有用的方式)
重复声明是错误
在全局范围内使用时,它们不会创建全局对象的属性(尽管创建全局变量;这是ES2015的新概念)
var 变量存在于它们声明的函数中(或全局地,如果全局声明),它们不限于它们所在的块.所以这段代码是有效的:
function foo(flag) {
a = 10;
if (flag) {
var a = 20;
}
return a;
}
console.log(foo(false)); // 10
console.log(foo(true)); // 20Run Code Online (Sandbox Code Playgroud)
a无论是否flag为真,它都被定义,并且它存在于if块之外; a以上三个都是相同的变量.
let(或const)不是这样的:
function foo(flag) {
if (flag) {
let a = 10;
}
return a; // ReferenceError: a is not defined
}
console.log(foo(true));Run Code Online (Sandbox Code Playgroud)
a只存在它在声明块中.(有关for声明,声明中()的for有效认为是块的一部分.)所以外if,a不存在.
let和const声明可以在封闭范围内影子声明,例如:
function foo() {
let a = "outer";
for (let a = 0; a < 3; ++a) {
console.log(a);
}
console.log(a);
}
foo();Run Code Online (Sandbox Code Playgroud)
那输出
0 1 2 outer
......因为a外for循环是不一样a的一个内部的for循环.
这是有效的代码:
function foo() {
a = 5;
var a = a * 2;
return a;
}
Run Code Online (Sandbox Code Playgroud)
奇怪的,但有效(它返回10),因为var在函数中完成任何其他操作之前完成,所以这是真的:
function foo() {
var a; // <== Hoisted
a = 5;
a = a * 2; // <== Left where it is
return a;
}
Run Code Online (Sandbox Code Playgroud)
这不是真的let或const:
function foo() {
a = 5; // <== ReferenceError: a is not defined
let a = a * 2;
return a;
}
Run Code Online (Sandbox Code Playgroud)
在声明之前,您不能使用该变量.该声明并未"悬挂"(好吧,它已被部分悬挂,继续阅读).
我早些时候说过
- 它们没有悬挂(好吧,它们有点悬挂,但是有用的方式)
"有点"?是.A let或const声明在整个出现的块中隐藏标识符,即使它实际上只在它出现的地方生效.示例帮助:
function foo() {
let a = "outer";
for (let x = 0; x < 3; ++x) {
console.log(a); // ReferenceError: a is not defined
let a = 27;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意"outer",我们收到错误而不是进入控制台.为什么?因为let a在for块阴影的a外块,尽管我们还没有得到它呢.块的开头和之间的空间let被规范称为"时间死区".单词不是每个人的事情,所以这是一个图表:
这是有效的代码:
function foo() {
var a;
// ...many lines later...
var a;
}
Run Code Online (Sandbox Code Playgroud)
第二个var被忽略了.
let(或const)不是这样的:
function foo() {
let a;
// ...many lines later...
let a; // <== SyntaxError: Identifier 'a' has already been declared
}
Run Code Online (Sandbox Code Playgroud)
JavaScript具有"全局对象"的概念,它将各种全局事物作为属性保存.在松散模式下,this全局范围是指全局对象,而在浏览器上有一个全局引用全局对象:window.(某些其他环境提供不同的全局,例如global在NodeJS上.)
在ES2015之前,JavaScript中的所有全局变量都是全局对象的属性.由于ES2015的,这仍然与那些宣称真正的var,但声明没有那些let或const.因此,var在全局范围内,在浏览器上使用此代码显示42:
"use strict";
var a = 42; // Global variable called "a"
console.log(window.a); // Shows 42, because a is a property of the global objectRun Code Online (Sandbox Code Playgroud)
但是此代码显示undefined了属性,因为let并且const在全局范围内不会在全局对象上创建属性:
"use strict";
let a = 42; // Global variable called "a"
console.log(a); // 42 (of course)
console.log(window.a); // undefined, there is no "a" property on the global object
const q = "Life, the Universe, and Everything"; // Global constant
console.log(q); // "Life, the Universe, and Everything" (of course)
console.log(window.q); // undefined, there is no "q" property on the global objectRun Code Online (Sandbox Code Playgroud)
最后的注释:如果你class用功能声明(而不是函数表达式)比较新的ES2015 (它提供了一个新的,更清晰的语法来创建构造函数和与它相关的原型对象),上述内容也是如此:
class声明具有块范围.相反,在流控制块中使用函数声明是无效的.(它应该是一个语法错误;相反,不同的JavaScript引擎以不同的方式处理它.有些将它重定位到流控制块之外,其他的就像你使用了函数表达式一样.)class声明没有悬挂; 函数声明是.class在同一范围内使用具有两个声明的相同名称是语法错误; 使用函数声明,第二个获胜,覆盖第一个.class全局范围内的声明不会创建全局对象的属性; 函数声明呢.提醒一下,这是一个函数声明:
function Foo() {
}
Run Code Online (Sandbox Code Playgroud)
这些都是函数表达式(匿名的):
var Foo = function() {
};
doSomething(function() { /* ... */ });
Run Code Online (Sandbox Code Playgroud)
这些都是函数表达式(命名的):
var Foo = function Foo() {
};
doSomething(function Foo() { /* ... */ });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5617 次 |
| 最近记录: |