回调定义关闭问题 [英] Callback definition closure issue

查看:79
本文介绍了回调定义关闭问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于定义回调的范围,我遇到了一些混乱。

I run into a bit of confusion regarding scoping with respect to where a callback is defined.

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






但是,以下操作无效


However, the following doesnt work

function test(){

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

    return fun
}

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

我希望该函数作为参数传递且之前未定义,其定义发生在 fun内部,因此可以访问b。相反,它看起来很像是函数首先在作用域中定义,然后将其作为参数传递。有想法/指针吗?

I would expect that since the function is passed as an argument and has not been defined before, its definition takes place inside 'fun' and therefore it would have access to b. Instead, it looks a lot like the function is first defined in the scope where its passed and THEN passed as an argument. Any ideas/pointers?

编辑:一些额外的指针。

someFunction("a")

我们不可能声称 a是一个定义。这里隐式发生的是, a被分配给了以参数名称命名的变量,因此 var argumentsNameInDefintion = a

We couldn't possibly claim that "a" is a definition. What happens here implicitly is that "a" is assigned to a variable named by the argument name so var argumentNameInDefintion = "a". This happens in the body of someFunction.

类似地,我们不能声明 {} 是以下内容的定义: someFunction({})。那为什么呢?

Similarly we cant claim {} is a definition in : someFunction({}). So why would:

someFunction(function(){})

决定 function(){} 是一个定义,这超出了我的范围。

decide that function(){} is a definition is beyond me. Had it been

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

一切都会很合理。

推荐答案

JavaScript的作用域是 lexical 。如果查看示例,则会发现 printingFunction 的定义是按词法(例如,在源文本中) b 在包含作用域中声明。但在第二个示例中,事实并非如此。这就是为什么 b 在第二个示例中无法解决,而在第一个示例中可以解决的原因。

Scoping in JavaScript is lexical. If you look at your examples, you can see that where printingFunction is defined, lexically (e.g., in the source text) b is declared in a containing scope. But in your second example, it isn't. That's why b can't be resolved in your second example but can in your first.

它的工作方式就是说,在创建函数时,它会引用一个包含变量的概念对象,并且该变量在其创建范围内(有一个漂亮的名字:词法环境对象);并且该对象引用了包含该对象的对象。当查找变量引用时,JavaScript引擎将查看当前的词法环境对象,如果找到该变量,则使用它。

The way it works is that when a function is created, it has a reference to a conceptual object containing the variables and such in the scope in which it's created (which has a fancy name: "Lexical Environment object"); and that object has a reference to the one that contains it. When looking up a variable reference, the JavaScript engine looks at the current lexical environment object and, if it finds the variable, uses it; otherwise, it looks to the previous one in the chain, and so on up to the global one.

更多详细信息,请参见:

More details can be found:

  • In this SO question's answers
  • In this post on my anemic little blog

这篇关于回调定义关闭问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆