作用域、作用域链、自由变量、变量提升

本文介绍了JavaScript中的作用域概念,包括全局作用域和局部作用域,并通过示例解释了变量的访问权限。作用域链决定了变量查找的顺序,而自由变量是指在当前作用域中引用但未定义的变量。此外,还讨论了变量提升的现象,以及在ES6中let和const如何避免此类问题。建议在函数中避免无var声明的全局变量,以维护代码的可维护性。
摘要由CSDN通过智能技术生成

作用域

  作用域经常被用来配合js引擎去查询访问权限。比如js引擎想要调用某一个变量就会先询问作用域自己能否取到该变量。得到作用域的许可后再执行后续步骤。引擎负责从头到尾整个js程序的编译和执行过程。
  所以作用域是负责收集、维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。
作用域分类

全局作用域(globe scope)和局部作用域(local scope)

全局作用域可以在代码中的任何地方都能被访问,例如:

var name1="haha";
function changName(){
    var name2="xixi";
    console.log(name1); // haha
    console.log(name2);// xixi
}
changName();
console.log(name1);//haha
console.log(name2);//Uncaught ReferenceError: name2 is not defined

其中,name1具有全局作用域,因此在第4行和第8行都会在控制台上输出 haha。name2定义在changName()函数内部,具有局部作用域,因此在第9行,解析器找不到变量name2,抛出错误。
  另外,在函数中声明变量时,如果省略 var 操作符,那么声明的变量就是全局变量,拥有全局作用域,但是不推荐这种做法,因为在局部作用域中很难维护定义的全局变量。

再者,window对象的内置属性都拥有全局作用域。

局部作用域一般只在固定的代码片段内可以访问得到,例如上述代码中的name2,只有在函数内部可以访问得到。

作用域链

在函数创建的时候,作用域链就形成了

变量的查找机制:当在一个作用域中访问一个变量的时候,首先查找的当前自己的作用域(AO)如果没有找到,就会去查询去查询父作用域的AO,如果也没有,就一直查询到全局gobal context 对象,找到了就返回,找不到就报错。这个查询层层递进形成一个链条 ,这个链条就是 作用域链

函数在被定义的时候,就通过{构造函数}.prototype.contructor.[[scope]]记录作用域链,并且函数会记住创建这个函数的环境(context)

自由变量

假如在全局中定义了一个变量,在函数中使用了这个变量,这个变量就是自由变量,也就是,凡是跨了自己的作用域的变量都叫自由变量

变量提升(js执行之前,浏览器将var提前声明为undefined,将function提前声明和定义)

变量提升只发生在当前作用域:
(1)开始加载页面时,只对全局变量进行提升,在函数内的声明的变量不被提升。
(2)执行函数时,私有作用域形成后,先形参赋值,然后变量提升,最后执行代码

在编译阶段,变量会被提前进行处理,如果有函数定义,则优先级高于变量定义

强调:函数的定义才会被提升,表达式不会

在ES6中使用 let const 定义变量,不会发生变量提升,同时不会出现重复变量

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值