首页 > 闭包传参作用域问题

闭包传参作用域问题

    (function () {
        var val = null;
        var callback;
        setTimeout(function () {
            val = 1;
            callback(val)
        },1000)
        window.getVal = function(fn){
            callback = fn;
        }
    })();
   //2作用域
    (function(){
        var b =3;
        getVal(function (val) {
            console.log(val);
            console.log(b);       //这里为什么还能打印出b这个变量呢/. 
        });
    })();

getVal函数中的匿名函数作为参数传递,另外一个作用域里面执行产生新的作用域,而且这个作用域指哪里?那为什么还能访问到b变量,并打印出来呢?

我的理解如下传参,代码变成如下;

    //1作用域
    (function () {
        var val = null;
        var callback;
        setTimeout(function () {
            val = 1;
           //callback(val)
            //传参后,函数在这里了,为什么还能访问到b呢,他应该向上,找不到才对啊?
            (function (val) {
                console.log(val);
                console.log(b);
            })(val)
        },1000)
        window.getVal = function(fn){
            callback = fn;
        }
    })();
    //2作用域
    (function(){
        var b =3;
        getVal(匿名函数传参);
    })();

函数作用域是声明时就决定了的,你创建的匿名函数,跟传哪里没关系,总是能访问b


js用的词法作用域,在定义时,就确定了作用域,而不是运行时


代码块1:

window.getVal = function(fn){
    callback = fn;//这里this指向的是window
}

代码块2:

getVal(function (val) {
    console.log(val);//
    console.log(b);       //这里为什么还能打印出b这个变量呢/. 
});

代码块3:

setTimeout(function () {
    val = 1;
    callback(val)
},1000)

代码块2执行的时候,执行环境中是可以访问到b这个变量的;
对于参数匿名函数当然也是能够访问的,因为这个匿名函数作为getVal的内部函数来用了,是能够访问外部变量的;

代码块1所定义的函数执行完,你又将这个能够访问b的函数的赋给了另一个作用域的callback变量,callback变量被强制指向了另一个作用域的内部函数,完美的形成了一个闭包;

代码块3执行的时候,外部变量callback已经被指向了你所设定的参数匿名函数,这时候成功调用函数并执行了

至于你说的作用域指向哪里? 应该是定义的函数以及变量对于当前作用域都有哪些是可见的,根据上面的分析你应该能自己构建一个简单的js执行环境作用域链了。


函数作用域是在声明时决定的,而不是调用时决定的。

虽然在那个函数内部调用了传入的函数,但是执行时会去声明该函数的位置寻找变量,如果内部没有,去外层函数查找,直到全局变量


因为你的getVal他是一个全局变量,闭包他只是封装了自己的变量,不让这个作用域之外的函数引用他,但是全局变量,每个函数都可以用!


如果无法访问b变量的话,javascript中就不存在闭包了!

 //2作用域
(function(){
    var b =3;
    getVal(function (val) {
        console.log(val);
        console.log(b);       //这里为什么还能打印出b这个变量呢/. 
    });
    //这里匿名函数其实就是一个闭包,你就相当于通过getVal函数把这个闭包传递出去了,你想想看,闭包是不是这样?
})();


 //2作用域
    (function(){
        var b =3;
        var ret = function (val) {
            console.log(val);
            console.log(b);
        }
        return ret;
    })();
    //这种写法更明白些。
【热门文章】
【热门文章】