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

 更新时间:2022年03月15日 15:04:24   作者:OceanWhite  
这篇文章主要给大家介绍了关于JavaScript块级作用域绑定以及状态提升的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

前言

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

作用域/执行上下文

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

  • 全局作用域/执行上下文:默认或者是最基础的作用域。一个程序只有一个全局作用域,在JavaScript脚本存在的生命周期中都在执行堆栈的底部不会被弹出销毁。全局作用域中有一个全局对象(以浏览器环境为例,这个全局对象是window)。
  • 函数作用域:一个函数体内部是一个作用域。
  • 块级作用域:存在于块中——字符 { 和 } 之间的区域。(显然函数体也是由大括号包裹的,所以函数作用域也是块级作用域)

var 声明

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

  • var声明的变量会被提升到当前作用域顶部(当前作用域只包括全局作用域或函数作用域,没有块级作用域)。

块级声明

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

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

  • let声明:可以将变量作用域限制在当前代码块中。在声明语句前会将变量放在临时死区。
  • const声明:用来声明常量,并且每个被被const声明的常量必须进行初始化。如果是对象,则对象中的值可以修改(cosnt声明不允许修改绑定,但可以修改绑定的值)

不声明的变量

在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 声明和块级声明的区别

全局作用域绑定

  • var声明在全局作用域中时,会创建一个新的全局变量作为全局对象的属性(在浏览器中为window对象)。这意味着用 var 可能会无意中覆盖一个已经存在的全局变量。
  • 块级声明(let 或 const)会在全局作用域创建一个新的绑定,但该绑定不会添加为全局对象的属性。所以用块级声明不会覆盖全局变量,只能遮蔽它。
let RegExp = 'Hello!'
console.log(RegExp);
console.log(window.RegExp === RegExp);
// 结果
/* 
Hello!
false
*/
复制代码

状态提升

  • var 声明的变量会提升到当前作用域顶部,在实例化之前为 undefined。var声明的变量限制范围为全局作用域或函数作用域。
  • 块级声明的变量会被存放到临时死区,在实例化前访问会报错 Uncaught ReferenceError
console.log(RegExp);
let RegExp = 'Hello!'
// Uncaught ReferenceError: Cannot access 'RegExp' before initialization

块级绑定的最佳实践

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

函数声明提升

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

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

总结

到此这篇关于JavaScript块级作用域绑定以及状态提升的文章就介绍到这了,更多相关JS块级作用域绑定/状态提升内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javascript Array.prototype.slice使用说明

    javascript Array.prototype.slice使用说明

    slice 可以用来获取数组片段,它返回新数组,不会修改原数组。
    2010-10-10
  • 修改js confirm alert 提示框文字的简单实例

    修改js confirm alert 提示框文字的简单实例

    下面小编就为大家带来一篇修改js confirm alert 提示框文字的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • javascript数组去重方法分析

    javascript数组去重方法分析

    这篇文章主要介绍了javascript数组去重方法,通过2个示例对比分析了javascript数组去重的原理与操作技巧,需要的朋友可以参考下
    2016-12-12
  • JS实现用户管理系统

    JS实现用户管理系统

    这篇文章主要为大家详细介绍了JS实现用户管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • 一文详解如何根据后端返回的url下载json文件

    一文详解如何根据后端返回的url下载json文件

    前后端分离的项目中,前端工作人员会要求后端返回指定格式的JSON数据,下面这篇文章主要给大家介绍了关于如何根据后端返回的url下载json文件的相关资料,需要的朋友可以参考下
    2022-05-05
  • postman自定义函数实现 时间函数的思路详解

    postman自定义函数实现 时间函数的思路详解

    Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。这篇文章主要给大家介绍postman自定义函数实现 时间函数的思路详解,感兴趣的朋友一起看看吧
    2019-04-04
  • js使弹层下面的body禁止滚动

    js使弹层下面的body禁止滚动

    这篇文章介绍了js使弹层下面body禁止滚动的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • js获取图片大小的函数代码

    js获取图片大小的函数代码

    工作小知识积累,获取图片的大小,需要的朋友可以参考下。
    2011-09-09
  • js鼠标点击图片实现随机变换图片的方法

    js鼠标点击图片实现随机变换图片的方法

    这篇文章主要介绍了js鼠标点击图片实现随机变换图片的方法,涉及鼠标事件与随机函数的使用技巧,需要的朋友可以参考下
    2015-02-02
  • Ajax实现不刷新取最新商品

    Ajax实现不刷新取最新商品

    本文主要介绍了Ajax 实现不刷新取最新商品的方法。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-03-03

最新评论