关于作用域和作用域链的总结
Posted hauner
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于作用域和作用域链的总结相关的知识,希望对你有一定的参考价值。
今天听了一个同事(到现在了,还不知道人家的名字,怪不好意思的。。。捂脸。。不准笑我)的分享会,主要讲的就是作用域和作用域链,感觉受益匪浅。与我自己的理解相结合,感觉对这两个哥们了解的更多了。把我的心得总结如下,看不懂的别问我,因为我也不懂。看得懂的请感谢我和我的同事,因为下面的东西我们两个经验的总结。当然了主要还是感谢我这位同事,毕竟我是在他高大的肩膀上站了一会才有的下面的体会。好了书归正传,咱们拉回来说正事。
在说正事之前先介绍几个关键字:var,let,const,function
var:很久以前的东西了,反正是很久以前就有它了。不过我肯定比他大。那么他是干啥的嫩。定义变量,而且能作变量提升,所谓的变量提升就是。还是看代码吧。
console.log(a) //undefined
Var a=1
结果是undefined,没有报错,因为程序在执行前,只要是本作用域下用var声明的变量都会做个提升声明,但不会赋值。
Let:也是声明变量的,这个我知道,是es6新出炉的一个关键字。先让我骄傲一下。哈哈哈哈。那么他能不能做变量提升呢?答案是不能的,要是和var一样的话就不会再弄个let了。还有就是他有块作用域了,而var是函数作用域。还是看代码
console.log(a) //报错
Let a=1
这次的输出结果是报错,这就是所谓的不能变量提升了那么什么又是块作用域呢,代码,对还是代码
{
let a=1
Var b=2
}
Console.log(b) //2
Console.log(a) //报错
这就是块作用域,只要在块外边他就没有a这个变量,不管是块前还是块后,查无此人。
Const:这个家伙也是es6新出的,但是她是声明常量的。代码说话
const a=0
console.log(a) //0
a= 1 //报错
Const同样是没有变量提升的,有块作用域,我就不代码演示了,同学们自己试去吧,毕竟纯手工打代码很累的。
Function:这位同志是声明函数用的,不皮了,代码
console.log(a)//function
a() //2
Function a(){console.log(2)}
同样的能够作提升,而且能够运行。不总结了,自己摸索去吧,其实我是不知道该怎么说了,毕竟水平比较低,共勉,勿笑。
值得一说的是还有一种无关键字声明变量,就是硬来,我也不说,直接干就是了。看下面的带码
function a(){
b=10
}
console.log(b)
//////////////////
function d(){
c=10
}
d()
console.log(c)
///////////////////
console.log(ff)
ff=10
三段代码,自己试试,自己悟。
介绍完了这几位老弟,下面来说一下作用域,其实作用域在上边的介绍中也说得差不多了,要不还是直接说作用域链吧,太晚了,一会还要睡觉呢。
作用域链这个东西还是要先说js的作用域机制,是什么能?就是作用域内能访问作用域外的变量、常量、函数等,反之就不行了,作用域外不能访问作用域内的变量。(这就好比一个小黑屋安装一个双面镜,猥琐的某人在里边看的清清楚楚,外边的美女不知道还在那里换衣服照镜子呢,因为他看不见里边呀。)还是代码说话
let a=1
function b(){
let c=2
console.log(a)
console.log(c)
}
b() //1 //2
console.log(a) //1
console.log(c) //2
不多解释了自己悟吧!还是重点说作用域链吧。
先说一下作用域链的原理和实现机制,js要执行一段代码先在创建一个Global Scope(全局作用域),同事老师说了叫GO(Global Object),然后他就会看代码里都有什么,所有的var /function声明的先做个提升,全部挂载GO下边。函数内部的再说,然后就执行了。遇到var的时候赋值,当遇到let,const的声明的时候挂载并赋值。当遇到function的时候,编译function内部,然后创建一个AO(Activation Object)他下边的所有声明挂载到AO下边,然后执行,再遇到function。。。。。。。。。。。。。。。。。。。。。。。。。。。。说不完的function太多了。用个代码加图看一下
let a = ‘a‘;
function b(){
let ba=‘ba‘;
bb = ‘bb‘;
(function(){
let ca=‘ca‘;
cb=‘cb‘;
})();
}
b()
先编译有了GO 然后又GO.a(属性) 和GO.b(方法)。然后执行遇到了GO.b又开始编译,又有了AO有了AO.ba(属性)和AO.nonamefn(方法),恩没看错没有AO.bb,只有GO.bb(属性)然后又执行匿名自执行函数,又有了一个AO就叫AO1吧号区分,然后又有了AO1.ca(属性)和GO.cb(属性)(不解释)
今天就先弄到这里吧,毕竟坐车到家就九点了,孩子妈带孩子回娘家了,还要自己做饭,吃完饭都9点半了,现在我都找到一点网文工作者的感觉了,为了您们能够明天看到我的博文,我也是拼了,不能断更啊。不管写个好不好,各位亲们都要给掌声。就像德云社卢鑫玉浩说得一样,敬请诸位上仙天雷滚滚,帮小生顺利渡劫。
以上是关于关于作用域和作用域链的总结的主要内容,如果未能解决你的问题,请参考以下文章
前端:如何理解 JS 的作用域和作用域链?说说闭包的两个应用场景
JavaScript中作用域和作用域链的简单理解(变量提升)