Lub*_*rek 240 javascript const let hoisting ecmascript-6
我已经玩ES6一段时间了,我注意到虽然声明的变量var按预期提升了......
console.log(typeof name); // undefined
var name = "John";
Run Code Online (Sandbox Code Playgroud)
... 用吊装声明let或const似乎有一些问题的变量:
console.log(typeof name); // ReferenceError
let name = "John";
Run Code Online (Sandbox Code Playgroud)
和
console.log(typeof name); // ReferenceError
const name = "John";
Run Code Online (Sandbox Code Playgroud)
这是否意味着变量声明let或未声明const?这是怎么回事?这个问题let和const这个问题有什么区别吗?
Ber*_*rgi 316
@thefourtheye说这些变量在声明之前无法访问是正确的.但是,它有点复杂.
与声明的变量
let或const不悬挂?这是怎么回事?
所有声明(var,let,const,function,function*,class)被"悬挂"在JavaScript.这意味着如果在范围中声明了名称,则在该范围内,标识符将始终引用该特定变量:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
Run Code Online (Sandbox Code Playgroud)
对于函数和块作用域1都是如此.
var/ function/ function*声明和let/ const/ class声明之间的区别是初始化.在作用域顶部创建绑定时,
前者使用undefined或者(生成器)函数初始化.然而,词汇声明的变量保持未初始化.这意味着ReferenceError当您尝试访问它时会抛出异常.只有在评估let/ const/ class语句时,才会初始化它,之前(上面)的所有内容称为时间死区.
x = y = "global";
(function() {
x; // undefined
y; // Reference error: y is not defined
var x = "local";
let y = "local";
}());
Run Code Online (Sandbox Code Playgroud)
请注意,let y;语句使用undefined类似的方式初始化变量let y = undefined;.
该时间盲区不是语法的位置,而是时间的变量(范围)的创建和初始化之间.只要不执行该代码(例如函数体或简单的死代码),引用声明上方代码中的变量并不是错误,如果在初始化之前访问变量,即使访问它也会引发异常代码在声明之下(例如,在过早调用的提升函数声明中).
这个问题
let和const这个问题有什么区别吗?
不,就提升而言,它们的工作原理相同.它们之间的唯一区别是const蚂蚁必须且只能在声明的初始化部分中分配(const one = 1;两者const one;以及后来的重新分配one = 2都是无效的).
1:当然,var声明仍然只在功能级别上起作用
the*_*eye 81
引用ECMAScript 6(ECMAScript 2015)规范let和const声明部分,
变量是在实例化包含词法环境时创建的,但在评估变量的LexicalBinding之前可能无法以任何方式访问它们.
所以,回答你的问题,是的,let并const提升,但在运行时评估实际声明之前你无法访问它们.
Tha*_*var 22
ES6介绍了出现的Let变量block level scoping.直到ES5我们没有block level scoping,所以在块内声明的变量总是hoisted在函数级别范围内.
基本上Scope是指程序中的变量可见的位置,它决定了允许使用已声明的变量的位置.在ES5我们有global scope,function scope and try/catch scope,ES6我们也通过使用Let获得块级别的范围.
var关键字定义变量时,从定义的那一刻起就知道整个函数.当您使用let语句定义变量时,它仅在已定义的块中已知.
function doSomething(arr){
//i is known here but undefined
//j is not known here
console.log(i);
console.log(j);
for(var i=0; i<arr.length; i++){
//i is known here
}
//i is known here
//j is not known here
console.log(i);
console.log(j);
for(let j=0; j<arr.length; j++){
//j is known here
}
//i is known here
//j is not known here
console.log(i);
console.log(j);
}
doSomething(["Thalaivar", "Vinoth", "Kabali", "Dinesh"]);
Run Code Online (Sandbox Code Playgroud)如果您运行代码,您可以看到该变量j仅在loop之前和之后都知道.然而,我们的变量从定义为止的那一刻就i已知entire function.
使用let还有另一个很大的优势,因为它创建了一个新的词汇环境,并且还绑定了新的价值而不是保留旧的引用.
for(var i=1; i<6; i++){
setTimeout(function(){
console.log(i);
},1000)
}
for(let i=1; i<6; i++){
setTimeout(function(){
console.log(i);
},1000)
}
Run Code Online (Sandbox Code Playgroud)
第一个for循环总是打印最后一个值,let它会创建一个新的范围并绑定新的值来打印我们1, 2, 3, 4, 5.
来了constants,它的工作基本上就像let,唯一的区别是它们的价值无法改变.在常量中允许变异,但不允许重新分配.
const foo = {};
foo.bar = 42;
console.log(foo.bar); //works
const name = []
name.push("Vinoth");
console.log(name); //works
const age = 100;
age = 20; //Throws Uncaught TypeError: Assignment to constant variable.
console.log(age);
Run Code Online (Sandbox Code Playgroud)
如果常量引用a object,它将始终引用object但是它object本身可以被更改(如果它是可变的).如果你想拥有一个不可变的object,你可以使用Object.freeze([])
在2015年的ECMAScript,let并const高挂,但没有初始化。在变量声明之前引用块中的变量会导致 a,ReferenceError因为从块的开始直到处理声明,变量都处于“时间死区”中。
console.log(x); // ReferenceError
let x = 3;
Run Code Online (Sandbox Code Playgroud)
在函数或脚本的顶层,函数声明被视为 var 声明而不是词法声明。
在变量声明之前引用块中的变量会导致 ReferenceError,因为从块的开始直到处理声明,变量都处于“时间死区”中。
下面的示例清楚地说明了“let”变量在词法范围/嵌套词法范围内的行为方式。
var a;
console.log(a); //undefined
console.log(b); //undefined
var b;
let x;
console.log(x); //undefined
console.log(y); // Uncaught ReferenceError: y is not defined
let y;
Run Code Online (Sandbox Code Playgroud)
变量 'y' 给出了一个引用错误,这并不意味着它没有被提升。该变量是在实例化包含环境时创建的。但是它可能无法访问,因为它位于无法访问的“时间死区”。
let mylet = 'my value';
(function() {
//let mylet;
console.log(mylet); // "my value"
mylet = 'local value';
})();
Run Code Online (Sandbox Code Playgroud)
let mylet = 'my value';
(function() {
let mylet;
console.log(mylet); // undefined
mylet = 'local value';
})();
Run Code Online (Sandbox Code Playgroud)
在示例 3 中,函数内新声明的“mylet”变量在 log 语句之前没有初始化器,因此值为“undefined”。
| 归档时间: |
|
| 查看次数: |
47819 次 |
| 最近记录: |