ECMAScript 6 引入了许可声明。
我听说它被描述为一个当地变量,但我仍然不确定它是如何行为不同于 var 关键词。
什么是差异?什么时候应该被允许使用而不是 var?
ECMAScript 6 引入了许可声明。
我听说它被描述为一个当地变量,但我仍然不确定它是如何行为不同于 var 关键词。
什么是差异?什么时候应该被允许使用而不是 var?
当前回答
// An array of adder functions.
var adderFunctions = [];
for (var i = 0; i < 1000; i++) {
// We want the function at index i to add the index to its argument.
adderFunctions[i] = function(x) {
// What is i bound to here?
return x + i;
};
}
var add12 = adderFunctions[12];
// Uh oh. The function is bound to i in the outer scope, which is currently 1000.
console.log(add12(8) === 20); // => false
console.log(add12(8) === 1008); // => true
console.log(i); // => 1000
// It gets worse.
i = -8;
console.log(add12(8) === 0); // => true
上面的过程不会产生所需的函数序列,因为我的范围超越了每个函数创建的区块的 iteration。 相反,在环节结束时,每个函数的 i 关闭指在环节结束时的 i 值(1000)为每个在 adder 中的匿名函数。
// Let's try this again.
// NOTE: We're using another ES6 keyword, const, for values that won't
// be reassigned. const and let have similar scoping behavior.
const adderFunctions = [];
for (let i = 0; i < 1000; i++) {
// NOTE: We're using the newer arrow function syntax this time, but
// using the "function(x) { ..." syntax from the previous example
// here would not change the behavior shown.
adderFunctions[i] = x => x + i;
}
const add12 = adderFunctions[12];
// Yay! The behavior is as expected.
console.log(add12(8) === 20); // => true
// i's scope doesn't extend outside the for loop.
console.log(i); // => ReferenceError: i is not defined
每个函数现在保留在函数创建时的 i 的值,并且 adderFunctions 按照预期行事。
现在,图像将两种行为混合在一起,你可能会看到为什么不建议在同一脚本中混合更新的Let和 const。
const doubleAdderFunctions = [];
for (var i = 0; i < 1000; i++) {
const j = i;
doubleAdderFunctions[i] = x => x + i + j;
}
const add18 = doubleAdderFunctions[9];
const add24 = doubleAdderFunctions[12];
// It's not fun debugging situations like this, especially when the
// code is more complex than in this example.
console.log(add18(24) === 42); // => false
console.log(add24(18) === 42); // => false
console.log(add18(24) === add24(18)); // => false
console.log(add18(24) === 2018); // => false
console.log(add24(18) === 2018); // => false
console.log(add18(24) === 1033); // => true
console.log(add24(18) === 1030); // => true
不要让这件事发生在你身上,使用灯具。
其他回答
主要差异是范围差异,而让它只能在所宣布的范围内可用,如在圆圈中,可在圆圈之外可访问,例如从MDN的文档(MDN的例子):
function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}`
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
当在区块内使用时,请将变量的范围限制在该区块上。
var a = 1;
var b = 2;
if (a === 1) {
var a = 11; // the scope is global
let b = 22; // the scope is inside the if-block
console.log(a); // 11
console.log(b); // 22
}
console.log(a); // 11
console.log(b); // 2
在基本上,
for (let i = 0; i < 5; i++) {
// i accessible ✔️
}
// i not accessible ❌
for (var i = 0; i < 5; i++) {
// i accessible ✔️
}
// i accessible ✔️
<unk>️ Sandbox 要玩 ↓
此分類上一篇
让
区块范围
在顶级(功能之外)
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined
在一个功能之内
(() => {
var functionScopedVariable = 42;
let blockScopedVariable = 43;
console.log(functionScopedVariable); // 42
console.log(blockScopedVariable); // 43
})();
console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
在一个区块内
{
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
}
console.log(globalVariable); // 42
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
在一个圈子里
用Let in Loops宣言的变量只能在该圈内提到。
for (var i = 0; i < 3; i++) {
var j = i * 2;
}
console.log(i); // 3
console.log(j); // 4
for (let k = 0; k < 3; k++) {
let l = k * 2;
}
console.log(typeof k); // undefined
console.log(typeof l); // undefined
// Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.
// Logs 3 thrice, not what we meant.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Logs 0, 1 and 2, as expected.
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 0);
}
临时死区
由于临时死亡区,使用声明的变量在被声明之前无法访问,试图这样做会导致错误。
console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;
没有重新宣布
var a;
var a; // Works fine.
let b;
let b; // SyntaxError: Identifier 'b' has already been declared
var c;
let c; // SyntaxError: Identifier 'c' has already been declared
格斯特
没有重新分配
const a = 42;
a = 43; // TypeError: Assignment to constant variable.
请注意,这并不意味着值是不可改变的;它的属性仍然可以改变。
const obj = {};
obj.a = 42;
console.log(obj.a); // 42
如果您想要一个不可变的对象,您应该使用 Object.freeze()。
const obj = Object.freeze({a: 40});
obj.a = 42;
console.log(obj.a); // 40
console.log(obj.b); // undefined
初步者需要
在使用 const 表示变量时,您必须始终指定值。
const a; // SyntaxError: Missing initializer in const declaration
答案缺少一点:
{
let a = 123;
};
console.log(a); // ReferenceError: a is not defined
var --> Function scope
let --> Block scope
const --> Block scope
是的
在此样本中,你可以看到我被宣布在一个如果区块. 但它被宣布使用 var. 因此,它获得功能范围. 它意味着你仍然可以访问变量 i 内部函数 x. 因为 var 总是被推到函数. 尽管变量 i 被宣布在一个如果区块, 因为它使用 var 它被推到主函数 x。
函数 x(){ if(true){ var i = 100; } console.log(i); } x();
现在变量 i 被宣布在函数 y. 因此, i 被定义为函数 y. 您可以访问 i 内部函数 y. 但不是从外部函数 y。
let, const
让和 const 有区块范围。
但是,差异是,当你将值分配给 const 时,你不能再分配。
console.log(x); var x = 100;
console.log(x); // ERROR let x = 100;