JS - 在外部函数外声明嵌套函数
JS - Declare nested function outside the outer function
案例 1:我明白为什么它在这种情况下有效:
function foo(arg) {
var outer = " this is the outer variable";
function bar() {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
bar();
}
console.log(foo("hello"));
情况 2:但我不明白为什么如果在外部单独声明 bar
函数,以下内容不起作用:
function foo(arg) {
var outer = " this is the outer variable";
bar();
}
function bar() {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
console.log(foo("hello"));
情况 3:如果我向 bar
函数添加参数:
function foo(arg) {
var outer = " this is the outer variable";
bar();
}
function bar(arg, outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
console.log(foo("hello"));
输出:
"arg: undefined"
"outer variable: " undefined
我的问题是关于案例 2:为什么 bar()
没有到达 foo()
中定义的变量?
编辑案例 2:
从所有反馈中吸取教训,我向 bar(arg, outer)
添加了参数,并且有效。非常感谢。
function foo(arg) {
var outer = " this is the outer variable";
bar(arg, outer);
}
function bar(arg, outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
console.log(foo("hello"));
有效。
函数参数仅在声明函数内部可见
因此 bar
函数无法访问 foo's
参数
你应该将参数传递给 foo 函数
function foo(arg) {
var outer = " this is the outer variable";
bar(arg); //<-------------
}
function bar(arg, outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
因为 bar
的词法范围是由它在代码中的位置定义的,而不是由它执行的链定义的。让我引用有关该主题的维基百科:
A fundamental distinction in scoping is what "part of a program"
means. In languages with lexical scope (also called static scope),
name resolution depends on the location in the source code and the
lexical context, which is defined by where the named variable or
function is defined. In contrast, in languages with dynamic scope the
name resolution depends upon the program state when the name is
encountered which is determined by the execution context or calling
context.
In practice, with lexical scope a variable's definition is resolved by
searching its containing block or function, then if that fails
searching the outer containing block, and so on, whereas with dynamic
scope the calling function is searched, then the function which called
that calling function, and so on, progressing up the call stack.[4] Of
course, in both rules, we first look for a local definition of a
variable.
换句话说,如果您在 foo
内声明 bar
,其词法范围将包括 foo
的词法范围。
无论从何处调用函数,甚至如何调用函数,其词法范围都是仅由函数声明的位置定义.
function foo(arg) {
var outer = " this is the outer variable";
function bar() {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
bar();
}
这里 bar 可以访问外部变量,因为它在其词法范围内,但在情况 2 中不能。
My question is regarding the case 2: why bar() doesn't reach the
variables defined inside the foo()?
outer
声明为 var
,这意味着它具有 函数范围 (它是 可在声明它的函数内部访问)。
因此,在 foo
之外(在 bar
中),outer 是不可访问的 除非它在 bar
或其父范围内声明(其中声明了 bar
的函数)。
来自评论
I assume the nested function can reach the variables defined inside
the outer function.
混淆似乎源于 bar
嵌套在 foo
中的想法 - 这是错误的.
bar
不是 foo
私有的,因为它没有在 foo
中声明,它在 foo
中声明与 foo
.
相同的范围
您没有将必要的参数传递给 bar 函数,第三个未定义是因为您没有在函数中返回任何内容,这将起作用:
function bar(arg, outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
return arg + outer;
}
function foo(arg) {
var outer = " this is the outer variable";
return bar(arg, outer);
}
console.log(foo("hello"));
我建议你仔细阅读这篇文章 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global.
outer
封装在 foo
中,因此在该函数之外没有对它的引用。
尝试将其作为参数传递
var outer = 'global var';
function foo() {
var inner = "this is the inner variable";
bar(inner);
}
function bar(arg) {
console.log("arg: " + arg);
console.log("outer var: " + outer);
}
When bar
is defined, its scope chain is created, preloaded with the
global variable object, and saved to the internal [[Scope]]
property.
When bar
is called, an execution context is created and its
scope chain is built up by copying the objects in the function’s
[[Scope]] property
所以,如果你给 bar
两个参数 arg,outer
,那就行得通了:
function foo(arg) {
var outer = " this is the outer variable";
bar();
}
function bar(arg,outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
console.log(foo("hello"));
Professional JavaScript for Web Developers.3rd.Edition.Jan.2012
p222
案例 1:我明白为什么它在这种情况下有效:
function foo(arg) {
var outer = " this is the outer variable";
function bar() {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
bar();
}
console.log(foo("hello"));
情况 2:但我不明白为什么如果在外部单独声明 bar
函数,以下内容不起作用:
function foo(arg) {
var outer = " this is the outer variable";
bar();
}
function bar() {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
console.log(foo("hello"));
情况 3:如果我向 bar
函数添加参数:
function foo(arg) {
var outer = " this is the outer variable";
bar();
}
function bar(arg, outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
console.log(foo("hello"));
输出:
"arg: undefined"
"outer variable: " undefined
我的问题是关于案例 2:为什么 bar()
没有到达 foo()
中定义的变量?
编辑案例 2:
从所有反馈中吸取教训,我向 bar(arg, outer)
添加了参数,并且有效。非常感谢。
function foo(arg) {
var outer = " this is the outer variable";
bar(arg, outer);
}
function bar(arg, outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
console.log(foo("hello"));
有效。
函数参数仅在声明函数内部可见
因此 bar
函数无法访问 foo's
参数
你应该将参数传递给 foo 函数
function foo(arg) {
var outer = " this is the outer variable";
bar(arg); //<-------------
}
function bar(arg, outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
因为 bar
的词法范围是由它在代码中的位置定义的,而不是由它执行的链定义的。让我引用有关该主题的维基百科:
A fundamental distinction in scoping is what "part of a program" means. In languages with lexical scope (also called static scope), name resolution depends on the location in the source code and the lexical context, which is defined by where the named variable or function is defined. In contrast, in languages with dynamic scope the name resolution depends upon the program state when the name is encountered which is determined by the execution context or calling context.
In practice, with lexical scope a variable's definition is resolved by searching its containing block or function, then if that fails searching the outer containing block, and so on, whereas with dynamic scope the calling function is searched, then the function which called that calling function, and so on, progressing up the call stack.[4] Of course, in both rules, we first look for a local definition of a variable.
换句话说,如果您在 foo
内声明 bar
,其词法范围将包括 foo
的词法范围。
无论从何处调用函数,甚至如何调用函数,其词法范围都是仅由函数声明的位置定义.
function foo(arg) {
var outer = " this is the outer variable";
function bar() {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
bar();
}
这里 bar 可以访问外部变量,因为它在其词法范围内,但在情况 2 中不能。
My question is regarding the case 2: why bar() doesn't reach the variables defined inside the foo()?
outer
声明为 var
,这意味着它具有 函数范围 (它是 可在声明它的函数内部访问)。
因此,在 foo
之外(在 bar
中),outer 是不可访问的 除非它在 bar
或其父范围内声明(其中声明了 bar
的函数)。
来自评论
I assume the nested function can reach the variables defined inside the outer function.
混淆似乎源于
bar
嵌套在foo
中的想法 - 这是错误的.bar
不是foo
私有的,因为它没有在foo
中声明,它在foo
中声明与foo
. 相同的范围
您没有将必要的参数传递给 bar 函数,第三个未定义是因为您没有在函数中返回任何内容,这将起作用:
function bar(arg, outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
return arg + outer;
}
function foo(arg) {
var outer = " this is the outer variable";
return bar(arg, outer);
}
console.log(foo("hello"));
我建议你仔细阅读这篇文章 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global.
outer
封装在 foo
中,因此在该函数之外没有对它的引用。
尝试将其作为参数传递
var outer = 'global var';
function foo() {
var inner = "this is the inner variable";
bar(inner);
}
function bar(arg) {
console.log("arg: " + arg);
console.log("outer var: " + outer);
}
When
bar
is defined, its scope chain is created, preloaded with the global variable object, and saved to the internal[[Scope]]
property. Whenbar
is called, an execution context is created and its scope chain is built up by copying the objects in the function’s [[Scope]] property
所以,如果你给 bar
两个参数 arg,outer
,那就行得通了:
function foo(arg) {
var outer = " this is the outer variable";
bar();
}
function bar(arg,outer) {
console.log("arg: " + arg);
console.log("outer variable: ", outer);
}
console.log(foo("hello"));
Professional JavaScript for Web Developers.3rd.Edition.Jan.2012
p222