回调定义关闭问题(Callback definition closure issue)

2019-10-28 14:33发布

我遇到了一些混乱关于针对其中一个回调定义作用域。

function test(){

    var b = 3
    var fun = function(){

        var printingFunction = function(){
            console.log(b)
        }
        printingFunction()
    }

    return fun
}

test()() //prints 3, as expected because of closures

但是,下列不工作

function test(){

    var b = 3
    var fun = function(cb){
        cb()
    }

    return fun
}

test()(function(){console.log(b)}) //b is not defined

我希望的是,由于函数作为参数传递,并没有被定义,它的定义发生内部“乐趣”,因此将有机会获得到B。 相反,它看起来很像功能首先在它的通过,然后作为参数传递的范围限定。 任何想法/指针?


编辑:一些额外的指针。

someFunction("a")

我们不可能要求“一”是一个定义。 什么隐含在这里发生的是,“一个”被分配给一个由参数名称,以便命名变量var argumentNameInDefintion = "a" 。 这发生在someFunction的身体。

同样,我们不能权利要求{}是在一个定义: someFunction({}) 那么,为什么会:

someFunction(function(){})

决定function(){}是一个定义是超越我。 如果这是

var a = function(){}
someFunction(a)

一切都将完全合理。 也许它是多么的语言工作。

Answer 1:

在JavaScript作用域是词法 。 如果你看一下你的例子,你可以看到,这里printingFunction定义,词汇(例如,在源文本) b是一个包含范围内声明。 但是,在你的第二个例子,事实并非如此。 这就是为什么b不能在你的第二个例子来解决,但可以在你的第一个。

它的工作方式是创建一个功能时,它具有含有(其具有奇特的名字:“词法环境对象”),其中它的创建的范围的变量和这样的引用的概念对象; 和该对象具有到包含它的一个的引用。 当寻找一个变量引用,JavaScript引擎着眼于当前词法环境对象,如果发现该变量,使用它; 否则,它看起来与前一个链条,依此类推,直到全球一个。

更多细节,可以发现:

  • 在这太问题的答案
  • 在这个职位上我的贫血小博客


Answer 2:

这个问题源于我不理解的是function(){}对自己是一个定义,所以是"a"{} 由于这些定义,然后通过函数的定义范围适当放置它在哪里,世界又是有道理的。



Answer 3:

在第一种情况下,它是在形成封闭并具有访问变量“b”,但在第二情况下,它不形成闭合的。 如果你只是在函数内部的CB()之前把一个调试器,你会发现,没有形成闭合和那个正在回调函数suplied给函数作为参数的原因,并成为局部的功能,确实没有变量b的任何知识。

把它看成是两个不同的功能,在其中它有一个局部变量“b”和其他任何局部变量,但我们正试图访问它会抛出的引用错误。



文章来源: Callback definition closure issue