当前位置:主页 > 网页前端 > JavaScript代码 >

JavaScript块级作用域绑定以及状态提升详解

时间:2023-03-12 11:24:49 | 栏目:JavaScript代码 | 点击:

前言

在ES6之前,JavaScript只有经典的var声明,这给开发者带来了很多的困扰。在ES6出现后,又增加了let和const关键字的声明方式。这里会讲有关变量声明,作用域,状态提升相关知识。

作用域/执行上下文

在JavaScript的世界里,作用域可以分为三种,分别是全局作用域,函数作用域,块级作用域。

var 声明

var声明在全局作用域中,会被添加到全局对象上成为全局对象的属性。在函数作用域中则会被提升到函数顶部。而且不管实际是否会执行,都会在预编译阶段将函数声明提升,初始化操作则留在本地。

块级声明

临时死区(Temporal Dead Zone,TDZ):用来描述 let 和 const 的不提升效果的术语。JavaScript引擎在扫描代码发现变量声明时,要么将他们提升到作用域顶部(var声明),要么将声明放到TDZ(let声明和const声明)。访问在TDZ中的变量会触发运行时错误,只有执行过变量声明语句后,变量才会从TDZ中移出,然后才可以正常访问。

const 和 let 是块级标识符,所以声明的变量、常量也只在当前代码块中有效,一旦执行到块外就会立即被销毁。

不声明的变量

在JavaScript中,定义一个变量不使用关键字声明也不会报错。但不建议这么做。

不管在全局,函数还是块作用域里,a = 0 这样的语句都会在 window 对象上创建 a 属性,实际上也就是执行了 window.a = 0 。而只有在全局作用域中,var a = 0才会在 window 上创建属性 a,即为 window.a = 0。

1. 不使用关键字声明变量

function func() {
    b = 0
    console.log(b);
    console.log(b === window.b);
}
func()
console.log(b === window.b);

// 输出结果
/*
0
true
true
*/

?? 这部分代码执行过 func 函数,将变量 b 作为 window 对象的属性。

2. 使用 var 声明的变量

function func(x) {
    var b = 0
    console.log(b);
    console.log(b === window.b);
}
func(1)            
console.log(b === window.b);

// 输出结果
/* 
0
false
Uncaught ReferenceError: b is not defined
*/

?? 这段代码就是正常的 var 声明的变量在函数作用域内提升。

var 声明和块级声明的区别

全局作用域绑定

let RegExp = 'Hello!'
console.log(RegExp);
console.log(window.RegExp === RegExp);
// 结果
/* 
Hello!
false
*/
复制代码

状态提升

console.log(RegExp);
let RegExp = 'Hello!'
// Uncaught ReferenceError: Cannot access 'RegExp' before initialization

块级绑定的最佳实践

默认使用 const,只有确实需要改变变量的值时使用 let。

函数声明提升

函数提升优先级高于变量提升。

函数声明的特点:函数声明会被提升到当前作用域顶部,并且可以在当前作用域内部任何地方都可以访问到。

总结

您可能感兴趣的文章:

相关文章