前言

我们知道所谓的闭包指的就是有权访问另一个函数作用域的变量对象的函数,但是你们真的了解JS的闭包吗?就当你们很了解了,毕竟是基础知识,我就简单说说

概念

var a = 'july';
function test () {
    var b = 'mirok';
    return function() {
        var c = 'inner'
        console.log(a);
        console.log(b);
    }
}
test()(); // mirok,july
console.log(c); // error: undefined

简单几行代码,先说说作用域链的流程,运行到test()时,会将作用域链保存到[[Scope]]中,执行到test()时会创建执行环境,并将复制[[Scope]]对象构建执行函数的作用域链。我们知道作用域链寻找规则是往前找的,而闭包是能够将外部函数的活动对象添加到作用域链中的,所以test函数里的闭包就包含了全局的活动对象和test的活动对象,自然就能输出a和b

注意

闭包需要注意的点是它只取外部函数变量最后一个值,例如以下demo:

 function test (){
    var arr = [];
    for (var i=0; i<3; i++) {
        arr[i] = function() {
            return i;
        }
    }
    return arr;
}
for (var i =0; i < test().length; i++) {
    console.log(test()[i]())
}
// 输出三个3

也就是说闭包里作用链中的外部函数的活动对象一直都是i,因为作用域链其实是指向活动对象的指针列表,所以当test返回时i是3,闭包里的也自然是都是3

this指向问题

我们知道this指向函数的执行环境,全局中调用指向window,对象调用指向该对象,但是在对象中函数的闭包的this又指向哪呢?先上代码

var env = 'window';
const obj = {
    env: 'Obj',
    showEnv: function() {
        return function() {
            console.log(this.env)// 输出window
        }
    }
}

输出window因为本身的this在闭包中就已经存在,因此不会去寻找Obj的this,再不通过call和apply调用的情况下,匿名函数的this指向window的

其实闭包就是这样一块东西

function test() {
    var a = 'mirok';
    function show () {
        var b = 'july';
        console.log(this);
        return a;
    };
    this.fun = show;
}
const obj = new test();
obj.fun(); // mirok

clipboard.png

看看Scopes就知道闭包是什么啦~很容易就能理解的


flayPig
460 声望379 粉丝

attemp to do something that is defferent.