【JavaScript】let与var的区别及变量、函数提升
有var与无var的区别
在函数内部,有var和没var声明的变量是不一样的。有var声明的是局部变量,没var的,声明的全局变量,所以可以借此向外暴露接口。
let与var的区别
在上面代码中,我们使用var语句声明变量x。因此,变量x的范围是函数范围。if语句内的变量x就是if语句外创建的变量x。因此,在你修改if语句块内变量x的值的时候,也会修改函数中变量x的所有引用的值。
为了避免这种情况,我们需要使用块级作用域,let语句允许你创建块级作用域的局部变量。
修改上面的代码片段,使用let语句声明变量:
在上面的代码中,我们使用let语句声明块级作用域的局部变量x。因此,在if语句内更新变量x的值不会影响if语句外的变量x的值。
变量提升
使用 let 声明的变量没有变量提升,这意味着使用let声明的变量不会移动到执行上下文的顶部。
上图中获得x时不会报错是因为变量提升,而用let语句声明的y报错ReferenceError是因为不会提升到执行上下文之上。
函数提升
在JavaScript中,可以通过两种方式来创建函数:
1)作为声明而创建的函数
2)作为表达式而创建的函数
作为声明或语句创建的函数作为一个整体提升到执行上下文的顶部。但是,作为表达式创建的函数会像变量一样提升。
上图中第一个例子在函数创建之前使用函数,会得到hello的输出,是因为作为语句创建的函数会当做一个整体被提升到执行上下文的顶部。
function foo1(){console.log("hello")};
foo1(); // helo
第二个例子在函数创建foo2作为表达式时,因为JavaScript会像普通变量一样提升它,然而foo2中的函数赋值发生在函数中,也就是创建作为表达式函数的地方,所以当尝试执行时会这样执行:
var foo2;
foo2(); // foo2 is not a function
综上,
- 函数语句随函数主体一起被提升到执行上下文的顶部。你可以在函数创建之前使用作为语句创建的函数。
- 函数表达式在创建之前不能使用。只有声明部分会被提升,赋值发生在创建函数的那一行。
重新声明变量
同一个函数或块中使用 var 重新声明一个变量时不会报错。
同一个函数或块中使用 let 重新声明一个变量时会出现语法错误。
暂时性死区
使用 let 声明的变量会导致暂时性死区。
在下面代码中,let x = x+6 将抛出x未定义的异常。
之所以会出现这个错误,是因为表达式(x+6)求得是if块范围内局部变量x的值,而不是函数范围内局部变量x的值。
上一篇: 静态持续性、无链接性
下一篇: 基于Xposed的hook实战