为什么这两个不同的代码产生不同的结果?
我的意思是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
答案 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)
在第一种情况下foo2
在foo
内定义,因此它可以访问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
- 之前是未定义的