深入理解js作用域

一、作用域说明

定义变量的区域,限定一个变量可访问的范围的,
作用域的本质是对象

在ES6环境下,包含3个作用域,全局作用域,函数作用域,块级作用域( {} ) (eval)

二、作用域种类

1、全局作用域

全局作用域在页面打开的时候创建,页面关闭的时候摧毁
缩写在script标签中的变量和函数,作用域为全局,而页面在任意位置可以访问到
在全局作用域中有全局对象window,代表一个浏览器窗口,由浏览器创建,可以直接用
全局作用域中声明的变量和函数会作为window的属性和方法保存

2、函数作用域

调用函数时,函数作用域会被创建,函数执行完毕,函数作用域会被摧毁
每调用一次函数就会创建一次新的函数作用域,他们是互相独立的
在函数作用域中可以访问到全局作用域的变量和方法,函数外的无法访问到函数里面的变量和方法
在函数作用域中访问变量和方法的时候,会在自身的作用域查找,如果查找不到,会到函数的上一层作用域查找,一直找到全局作用域(就近原则)

3、块级作用域

( {} ) (eval)

三、作用域深层次的理解

1、执行期的上下文

当全局代码的前期会创建一个执行期的上下文的对象GO
当函数代码执行的前期,会创建一个执行期上下文的内部对象AO(作用域)
这个内部的对象是在预编译的时候创建出来的,因为函数被调用的时候,会先进行预编译

2、函数作用域预编译

1、创建oa(action object)对象 ,ao对象是函数执行前的一瞬间,生成一个AO对象(在函数执行前的一瞬间会生成自己的AO,如果函数执行2次,生成了两次AO,这两次的AO是没有任何关联)
2、找形参和变量声明,将变量和形参名 当做ao对象的属性值 值为undefined
3、实参形参相统一,形参作为实参的值
4、在函数体里面找函数声明 函数名作为GO对象的属性名,值赋值函数体

3、全局作用域预编译

1、创建GO(global object)对象
2、找函数声明 将变量名作为GO对象的属性名 值是undefined
3、找函数声明 ,函数名作为GO对象的属性名,值赋值函数体

4、作用域链

由多级作用域对象,逐级引用的链式结构。作用域的嵌套将形成作用域链,函数的嵌套将形成闭包,函数的嵌套在产生了链式关系的多个作用域的同时,也形成了一个闭包。
本质为执行上下文的scope属性,存储所有的变量,包括局部与全局,控制变量的使用顺序。
他是AO和GO的集合,
它会被保存到一个隐式的属性【scope】 这个属性是我们用户访问不到的,是给js引擎预编译的时候访问的

5、静态作用域

作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。

JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。函数的作用域在函数定义的时候就决定了。

var value = 1;

function foo() {
    console.log(value);
}

function bar() {
    var value = 2;
    foo();
}

bar();

// 结果是 ???

执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值