文体两开花 ,说道闭包就必需要说下做用域;说道做用域我就想到了做用域链,说道做用域链,我就想到了执行期上下文,说道执行期上下文,我就想到了预编译。因此为了说下闭包,就得从预编译提及。(第二次写文章,文笔不怎么好,加上内容自己难度挺大,请多多包涵,仔细阅读,看懂每个字,理解图片中的每个字)
众所周知js两大特色 1.单线程;2.解释执行(解释一行,执行一行)。那么问题来了 以下代码的输入结果是什么?
javascript
console.log(a,b)
function a(){}
var b = 0;复制代码
解释一行执行一行, 第一句直接console.log(a,b), 尚未执行到他们的 声明语句,那结果会不会是 xxx is not defient 。 明显不是,稍微有点基础的人都知道 var 和 函数声明会有提高。 这个提高为 函数声明总体提高 , 变量 声明提高。这个提高的过程就是发生在预编译。可是预编译不止这些。
前端
先介绍一波知识点:java
js运行三部曲:对函数:预编译发生在函数执行前一刻;node
对整js :预编译发生在全局执行的前一刻;es6
那么问题来了:函数声明和变量声明都提高谁的优先级高呢?面试
看码:bash
function fn(a) {
console.log(a)
console.log(b)
var a = 123;
console.log(a)
function a(){}
var b = function(){}
console.log(b)
function d (){}
}
fn(1)复制代码
上面的代码分别输出什么,能够本身先看看有了答案,再往下看。闭包
在回答上面的问题前先列出 函数预编译4步曲:函数
全局的预编译,省略 2.的找形参和 3步的实参和形参统一;
ui
如今来回答上面的问题:
下面给出2个题,而后结束预编译。(你们能够先本身坐下,再去本身打下代码,若是跟本身的答案个控制台输出有出入,就看再看看4部曲再作作。熟悉了再往下看哟)
console.log(test);
function test(test) {
console.log(test)
var test = 234;
console.log(test)
function test(){}
}
test(1)
var test = 123;复制代码
function test (a,b){
console.log(a);
c = 0;
a = 3;
b = 2;
console.log(b);
function b(){}
function d(){}
console.log(b)
}
test(1);复制代码
来看码:
function a() {
function b(){
var b = 234;
}
var a = 123;
b();
}
var glob = 100;
a();复制代码
第二步:a执行,生成了本身的AO,插入到了[[scopes]] 0 位GO 日后延
第三步:a执行引发的b的定义,这个时候b继承了a的劳动成果,直接把a的生成的做用域链的引用拿来挂到本身的身上。这个时候 b.scope[0] 指向的AO和 a.scope[0] 指向的AO是同一个。(结合一下本身写代码就能知道,在子函数里面改变了外部函数的值,外部函数的值也改变了)
第四步:b函数执行,生成了本身的AO,把本身的AO插入到刚刚获取的做用域链
function a (){
function b(){
function c(){
}
c();
}
b();
}
a();复制代码
看了这个例子,你们应该能明白点了,(如何还没明白,怪我,第二次写文章,表达很差) 上面全部的AO和BO 都是一个AO和BO,他们拿到地址指向后就能够直接用,一个修改所有都被修改。
讨论以前,先说一句话,一句开始我加粗了的话 :当函数执行完毕,执行上下文被销毁
function a () {
function b() {
var bbb = 234;
console.log(aaa)
}
var aaa = 123;
return b;
}
var glob = 100;
var demo = a();
demo();复制代码
到这里文体两开花学闭包就结束了。至于闭包的用处和规避措施。你们就能够网上搜索了,不少。(如何没有看懂,是个人问题,文笔太差, 你们多多包涵,有问题欢迎评论区 指出,我看到就会立刻回复,谁叫我没工做呢)。
最后祝各位前端攻城师们都能对js了如指掌,虽然不少js的一些特性(或者说缺陷)确实恶心,可是说不定哪一天就被触发了,若是对这些不了解,那bug是真的找不到了。
ps:最后的最后打个广告,本人普通二本软件工程大四学生,js基础还行,了解一点node,其余的前段技术也多多少少了解点。正在找一份前端开发的工做,坐标成都。但愿有找人的大佬,给点内推,面试机会。谢谢大佬们。