使用回调的函数上下文

时间:2012-02-25 22:35:38

标签: javascript

为什么这两个不同的代码产生不同的结果?

我的意思是foo2,在第一个代码中定义,而callback在第二个代码中是相同的,它们在foo内的相同上下文中执行。

第一个代码:

var foo = function () {
   var bar = 2;
   var foo2 = function () {
     console.log("bar: ", bar);
   }
   foo2();
}

foo() // 2

第二段代码:

var foo = function (callback) {
   var bar = 2;
   callback();
}

var callback = function () {
   console.log(bar);
}

foo(callback); // ReferenceError: bar is not defined

6 个答案:

答案 0 :(得分:2)

在第二个函数中,bar超出范围 - 它只存在于函数“foo()”中;在函数“callback()”中,bar不存在,这就是为什么你得到的栏没有定义错误。我会将其更改为接受参数并打印该参数,如下所示:

var foo = function (callback) {
   var bar = 2;
   callback(bar);
}

var callback = function (bar) {
   console.log(bar);
}

通过这种方式,回调将打印传入的bar值。另一种方法(取决于你的应用程序,但通常可以被认为不太推荐)将bar定义为一个全局变量,在任一函数之外:

var bar = 2;

var foo = function (callback) {
   callback();
}

var callback = function () {
   console.log(bar);
}

无论哪种方式都有效,但第一种方法是更好地封装代码而不使用全局变量。

编辑:这是第一种方法的一个不那么令人困惑的版本,为了便于阅读,最好不要在两种不同的用途中使用“bar”变量名:

var foo = function (callback) {
   var bar = 2;
   callback(bar);
}

var callback = function (myBarParam) {
   console.log(myBarParam);
}

希望这有用!

答案 1 :(得分:1)

简短的回答,只是因为你从某个地方调用一个函数,并不意味着函数可以访问你调用它所在范围内定义的所有内容。但是,它可以访问定义范围内的所有内容。在第一种情况下,当定义时,它可以访问bar。在第二个示例中,当定义时,它无法访问bar,因此当您调用它时它会抱怨。

答案很长:https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope

答案 2 :(得分:1)

在第一种情况下foo2foo内定义,因此它可以访问foo有权访问的所有本地人。当它绑定bar时,它无法在foo2中找到它,然后查看foo并使用它在那里找到的那​​个。

callback案例中,它是在foo之外定义的。因此,它看不到任何foo本地人,而是结束了该值未定义

答案 3 :(得分:1)

由于功能范围。 (含义变量只能在声明它们的范围内访问,或在范围链中声明(阅读))

在你的第二个例子中,这变成了克莱尔。 callback()在i全局范围内声明。当foo()然后调用callback()时,bar变量将不可见,因为bar是在另一个函数(foo())中声明的。如果你在函数之外声明了bar(在全局范围内),它可以从任何地方访问,也就是在任何函数内部。

这样可行:

var bar = 2;

var foo = function () {
    callback();
}

var callback = function () {
    console.log(bar);
}

foo();

在你的第一个例子中,你可以访问bar,即使它没有在foo2()中声明。这只是因为如果javascript引擎找不到您尝试使用的变量,它会在“父”函数(或范围)中查找相同的变量。这被称为范围链。

答案 4 :(得分:0)

在两个示例中,您将bar声明为函数foo的上下文。 该变量将在foo上下文及其所有“子上下文”中可用。

在第一个示例中,您在foo上下文中声明了第二个函数 ,因此您可以访问bar

在第二个示例中,未在 foo上下文中声明回调。 <{1}}无法进行回调,但不存在。

答案 5 :(得分:0)

var foo = function (callback) {
   var bar = 2;
   callback(bar);
}

var callback = function (baz) {
   console.log(baz);
}

foo(callback);

看到区别:foo里面的bar是回调中的baz - 之前是未定义的