Ret*_*n-1 0 javascript closures
关于定义回调的位置,我遇到了一些混乱.
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
Run Code Online (Sandbox Code Playgroud)
但是,以下不起作用
function test(){
var b = 3
var fun = function(cb){
cb()
}
return fun
}
test()(function(){console.log(b)}) //b is not defined
Run Code Online (Sandbox Code Playgroud)
我希望由于函数作为参数传递并且之前没有定义过,它的定义发生在'fun'中,因此它可以访问b.相反,它看起来很像函数首先在其传递的范围中定义,然后THEN作为参数传递.任何想法/指针?
编辑:一些额外的指针.
someFunction("a")
Run Code Online (Sandbox Code Playgroud)
我们不可能声称"a"是一个定义.这里隐含的是"a"被赋给由参数名称so命名的变量var argumentNameInDefintion = "a".这发生在someFunction的主体中.
同样,我们不能声称{}是一个定义:someFunction({}).那么为什么会:
someFunction(function(){})
决定这function(){}是一个超越我的定义.如果是的话
var a = function(){}
someFunction(a)
Run Code Online (Sandbox Code Playgroud)
一切都会很有道理.也许它只是语言的运作方式.
JavaScript中的范围是词汇.如果查看示例,可以看到printingFunction定义的位置,词法(例如,在源文本中)b在包含范围内声明.但在你的第二个例子中,事实并非如此.这就是为什么b在第二个例子中无法解决的原因,但可以在你的第一个例子中解决.
它的工作方式是,当一个函数被创建时,它有一个对包含变量的概念对象的引用,以及它在创建它的范围内的引用(它有一个奇特的名字:"Lexical Environment object"); 并且该对象具有对包含它的引用的引用.查找变量引用时,JavaScript引擎会查看当前的词法环境对象,如果找到该变量,则使用它; 否则,它会查看链中的前一个,依此类推全局链接.
更多细节可以找到: