凭什么只有我不能触摸她的心?JavaScript的作用域?作用域链?预编译?

前言

凭什么后来者居上?凭什么她的心只有我不能触摸?(o(╥﹏╥)o)

让我从JavaScript中的作用域、作用域链和预编译开始聊聊,相信你一定能从中有收获的

什么是的作用域?

简单来说就是能被访问的区域,在JavaScript中分为三种作用域,全局域、函数域和块级作用域,这里就不做细说了,可参考我的上一篇文章《浅谈JavaScript中的作用域》

什么是作用域链?

简单来时说就是一个一个作用域连起来,成了一条链子,有点抽象,看看图吧

image.png
这个关系可以一直套娃的,小的可以访问大的,大得不能访问小的,就好比在你心里深处的她,她已经参透你,拿捏你,可你却完全看不懂她

什么?你说我怎么在最里面?我劝你最好别问,怕你难过

来点专业点的解释

作用域链是一个由多个变量对象组成的链条,在引擎进行预编译的时候,会把当前作用域内的函数声明和变量声明等信息收集起来,形成一个变量对象。之后再将这个变量对象与父作用域的变量对象链接起来,不断重复,最终就构成了作用域链

什么是预编译?

简单来说就是,代码在执行前需要进行编译操作,用于确定代码之间的各种关联

情人节送礼物不得先看看你和她的关系?

别看了,你不在她心里,你收不到礼物的!!!

什么?你说为什么你送给她的礼物在我手里?那我只能说你不懂作用域链

不懂没事,继续往下,我给你捋捋

关系

通过一个一个作用域的关联,形成作用域链

为什么作用域能够清晰划分呢?他里面的变量凭什么我就不能访问?

预编译就是为了帮助作用域链去进行变量查找

现在知道为什么我收到了你的礼物了吧,情人节我和她要,她可不就和你要了?

预编译过程(重点)

每个函数都有一个内部属性[[scope]]用于存储函数中的有效标识符

在编译时

  1. 变量声明,声明提升 如:var a = 10 中声明提升 var a 后面才是a=10 而不是整体提升var a = 10
  2. 函数声明,整体提升

在全局和函数体内流程有所不同

  • 全局

    1. 创建GO对象
    2. 找变量声明,将变量名作为GO的属性名,值为undefined
    3. 在全局找函数声明,将函数名作为GO的属性名,值为该函数体
  • 函数体内

    1. 创建一个AO对象
    2. 找形参和变量声明,将形参和变量名作为AO的属性名,值为undefined
    3. 形参和实参统一
    4. 在函数体内找函数声明,将函数名作为AO的属性名,值为该函数体

这段代码如何编译的?

function test() {

}

函数调用,在引擎中创建这个函数的执行上下文对象,称之为AO action object,记录有效标识符,执行完之后会被回收掉

image.png

那么这段代码会如何编译呢?

function a() {
    function b() {
        b = 22;
    }
    var a = 111;
    b();
    console.log(a);
}
var glob = 100;
a();

我们来分析一下

首先会创建GO,GO里面存放着变量、函数,并且变量的值为undefined

image.png

创建完毕后,开始调用,调用a()后,创建AO对象,将形参和变量名作为AO的属性名,值为undefined,形参和实参统一,在函数体内找函数声明,将函数名作为AO的属性名,值为该函数体

image.png

其实这个就是该段就是函数a的作用域链

image.png

当执行a时又发现了b函数,于是就又给b创建作用域了,b的作用域首先肯定是指向a的作用域的,因为是a的执行带来了b的创建

image.png

后来执行b了,于是给b创建内部的作用域

image.png

接下来分析这段代码会输出什么?

function fn(a){
    console.log(a);
    var a = 123;
    console.log(a);
    function a(){}
    console.log(a);
    var b = function(){}
    console.log(b);
    function c(){}
    var c = a
    console.log(c);
}
fn(1);

第一次创建GO对象

GO{
    fn:function
}

执行后创建a的oa对象

AO{
    a:undefined 1 function
    b:undefined
    c:undefined function 123
}

所以执行后结果问为function 123 123 function 123

总结

相信看完本章你一定能明白()

凭什么只有你不能触摸她的心?

为什么你送给她的礼物在我手里?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值