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

csdn推荐

前言

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

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

什么是的作用域?

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

什么是作用域链?

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

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

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

来点专业点的解释

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

什么是预编译?

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

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

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

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

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

关系

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

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

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

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

预编译过程(重点)

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

在编译时

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

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

这段代码如何编译的?

function test() {
}

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

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

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

我们来分析一下

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

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

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

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

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

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

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

总结

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

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

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

文章来源:https://blog.csdn.net/weixin_56440777/article/details/139710317



微信扫描下方的二维码阅读本文

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容