【前端知识】JavaScript——var 与 let 的区别
-
var声明的变量会自动提升到函数作用域顶部,而let不会。
在解析代码时,JavaScript 引擎会注意出现在块后面的 let 声明,只不过在此之前不能以任何方式来引用未声明的变量。在 let 声明之前的执行瞬间被称为
暂时性死区(temporal dead zone)
,在此阶段引用任何后面才声明的变量都会抛出 ReferenceError。
-
let的声明的范围是块作用域,而var声明的范围是函数作用域
如下图,变量
x_let
之所以不能在 if 块外部被引用,是因为它的作用域仅限于该块内部。而由于x_var
的作用域为整个函数,所以它能够在if块外部被引用。
- let不允许许同一个块作用域中出现冗余声明,而var允许。
- let 在全局作用域中声明的变量不会成为 window 对象的属性,而var 声明的变量则会。
var x_var = 'x_var';
console.log(window.x_var); // 'x_var'
let x_let = 'x_let';
console.log(window.x_let); // undefined
- let 不能用于条件声明,而var可以。
<script>// 假设脚本不确定页面中是否已经声明了同名变量// 针对var: 它可以假设还没有声明过,因为多个重复声明可以被作为一个提升声明来处理var name = 'Matt'; // 针对let: 它的作用域为块,不会检查之前是否声明过同名变量,如果 age 之前声明过,则会报错let age = 36;
</script>
使用 try/catch 语句或 typeof 操作符也不能解决,因为条件块中 let 声明的作用域仅限于该块:
<script> if (typeof name === 'undefined') { let name; } // 上面的 name 被限制在 if {} 块的作用域内,因此这个赋值形同全局赋值name = 'Matt'; try { console.log(age); // 如果 age 没有声明过,则会报错} catch(error) { let age;} // age 被限制在 catch {}块的作用域内,因此这个赋值形同全局赋值
</script>
- 在for循环中,若迭代变量采用var声明,会渗透到循环体外,而let则无此问题