
JavaScript:了解下let/var/function的变量。
let存在提升
对于let是否存在提升这个问题,让我们先来看以下这段代码:
a = "global";
(function() {
console.log(a); // undefined, 而不是打印出global
var a;
}());
{
console.log(a); // Uncaught ReferenceError: Cannot access 'a' before initialization
let a = 1;
}对于在函数作用域下打印出undefined,我们应该不奇怪。但引起我注意的是在块作用域下,抛出引用错误的原因是在初始化之前找不到a。那有没有可能a在创建过程被提升?而在我发现ES文档中存在[var/let hoisting],这让我有理由猜测let存在提升,只是由于暂时性死区的原因,我们不能在let a之前使用 a。
为了证明我的猜想,我想先从let声明的创建、初始化和赋值过程入手。
{
let a = 0;
a = 1;
}上述的代码块中发生的过程如下:
找到所有用
let声明的变量,在环境创建变量;执行代码;
执行
a=0,将a初始化为1;执行
a=1,对a进行赋值。
由该过程可知,如果我们在创建完变量后和初始化之前执行log()方法,控制台将会报错:
let a = 'global'
{
console.log(a) // Uncaught ReferenceError: Cannot access 'a' before initialization
let a = 1
}由此一来我们就可以知道了let在创建的过程被提升,而在初始化过程没有被提升。
var/function的变量提升
接下来我们来看看function/var的创建、初始化和赋值过程,由此看看能否探究出它们的差别。
2.1 var的变量提升
function foo() {
console.log(a); // undefined
var a = 0;
var b = 1;
}
foo();当我们执行foo()时,发生以下过程(较为省略):
为
foo创建环境;找到
foo中所有被var声明的变量,在这个环境中创建变量;将变量初始化为 undefined;
执行代码;
将
a赋值为0,b赋值为1。
由此我们可以知道var声明在代码执行前创建变量并初始化,所以当我们在var a = 0之前执行log(a)方法会得到 undefined 的结果。
2.2 function的变量提升
foo('btqf');
function foo(name) {
console.log("my name is" + name) // my name is btqf
}当我们执行foo函数时,发生以下过程:
找到所有
function声明的变量,在环境中创建变量;将这些变量初始化并赋值;
执行代码。
由此可见,function声明在代码执行前就创建、初始化并赋值。
总结
let的「创建」过程被提升了,但是初始化没有提升。var的「创建」和「初始化」都被提升了。function的「创建」「初始化」和「赋值」都被提升了。函数和变量相比,会被优先提升,即函数会被提升到更靠前的位置。
值得一提的是const与let基本类似,唯一的区别在于const只有创建和初始化,没有赋值过程。





网友评论文明上网理性发言 已有0人参与
发表评论: