javascript 参数和范围
javascript parameters and scopes
对这个 Eloquent Javascript explanation 参数和范围有点困惑。
它指出在函数外部声明的变量是全局变量,在函数内部声明的变量是局部变量,在函数内部声明的没有前面 var
的变量本质上是引用一个类似命名的全局变量。美好的。这就说得通了。但是这段代码让我陷入了循环。
var x = "outside";
var f1 = function() {
var x = "inside f1";
};
f1();
console.log(x);
// → outside
var f2 = function() {
x = "inside f2";
};
f2();
console.log(x);
// → inside f2
在第一个函数中注销 x 的值 应该 导致 "inside f1" 因为该变量是在本地声明的。第二个函数(因为它包含一个没有声明 var
的变量,因此引用了在最顶部声明的全局变量) 应该 导致 "outside." 但是...在任何一种情况下都不会。
我明白了应该发生的事情的要点。但除非我读错了,否则它似乎与作者描述的相反。这不可能是错别字。
f1
中的 x
是一个新变量 只能在 f1
中访问,并且对第一个全局 x
。为了清楚起见,您问题中的示例代码基本上可以像下面这样编写:
var globalX = "outside";
var f1 = function() {
var localF1X = "inside f1";
};
f1();
console.log(globalX); // → outside
var f2 = function() {
globalX = "inside f2";
};
f2();
console.log(globalX); // → inside f2
在 JavaScript 中,变量的作用域在函数级别(如果您在函数外部声明变量,则为全局级别)。
您可以在此处阅读有关 JavaScript 变量和 "hoisting" 的更多信息:http://javascriptissexy.com/javascript-variable-scope-and-hoisting-explained/
因此:
var x = 'a';
function f1() {
var x = 1;
console.log(x);
}
f1(); //outputs 1
console.log(x); //outputs 'a'
function f2() {
x = 'b';
}
console.log(x); //still outputs 'a'
f2();
console.log(x); //now outputs 'b'
在函数内部声明的变量只能从这些函数内部访问(或scoped)。如果是这样的话样本可能会更清楚:
function f1() {
var x = "Inside f1";
}
console.log(x);
将导致
ReferenceError: x is not defined
但是,如果函数的变量声明时没有 var
,那么函数就是 implicit global(要么是不好的做法,要么是遗漏了错误):
function f2() {
y = "Inside f2";
}
console.log(y);
将按您预期的方式工作,同时还声明一个隐式全局变量。
值得一提的是"use strict";
,其中运行ES5's Strict Mode. You generally want to declare this inside a function, which causes the function to be run in strict mode, and avoids the semantics of strict mode from breaking interoptability中的代码与其他代码。
function f3() {
"use strict";
z = "Inside f3";
}
console.log(z);
将导致
ReferenceError: z is not defined
因为严格模式不允许您声明隐式全局。
根据您的评论澄清,隐式全局变量将 "overwrite" 彼此。更明确地使用 JavaScript 术语:
x = 10
将在环境的全局对象 x
上声明一个 属性,window.x
用于浏览器环境,global.x
用于 Node/IO 环境。
x = 20
将重新定义上面讨论的 属性。
这里有一个小片段,您可以在任何环境中 运行 证明这一点。我绝不是说你应该使用隐式全局变量,而是提供另一个例子来说明你为什么不应该使用。
function functionThatNeedsGreaterThan50(value) {
// Skip checking the parameter because we trust the
// other developers on the team to make sure they call
// this right.
}
function f4() {
q = 42;
}
function f5() {
q = 62;
}
f4();
f5();
console.log(q);
// sometime thousands of calls later, one of which was
f4();
// I thought this was 62 but
functionThatNeedsGreaterThan50(q);
对这个 Eloquent Javascript explanation 参数和范围有点困惑。
它指出在函数外部声明的变量是全局变量,在函数内部声明的变量是局部变量,在函数内部声明的没有前面 var
的变量本质上是引用一个类似命名的全局变量。美好的。这就说得通了。但是这段代码让我陷入了循环。
var x = "outside";
var f1 = function() {
var x = "inside f1";
};
f1();
console.log(x);
// → outside
var f2 = function() {
x = "inside f2";
};
f2();
console.log(x);
// → inside f2
在第一个函数中注销 x 的值 应该 导致 "inside f1" 因为该变量是在本地声明的。第二个函数(因为它包含一个没有声明 var
的变量,因此引用了在最顶部声明的全局变量) 应该 导致 "outside." 但是...在任何一种情况下都不会。
我明白了应该发生的事情的要点。但除非我读错了,否则它似乎与作者描述的相反。这不可能是错别字。
f1
中的 x
是一个新变量 只能在 f1
中访问,并且对第一个全局 x
。为了清楚起见,您问题中的示例代码基本上可以像下面这样编写:
var globalX = "outside";
var f1 = function() {
var localF1X = "inside f1";
};
f1();
console.log(globalX); // → outside
var f2 = function() {
globalX = "inside f2";
};
f2();
console.log(globalX); // → inside f2
在 JavaScript 中,变量的作用域在函数级别(如果您在函数外部声明变量,则为全局级别)。
您可以在此处阅读有关 JavaScript 变量和 "hoisting" 的更多信息:http://javascriptissexy.com/javascript-variable-scope-and-hoisting-explained/
因此:
var x = 'a';
function f1() {
var x = 1;
console.log(x);
}
f1(); //outputs 1
console.log(x); //outputs 'a'
function f2() {
x = 'b';
}
console.log(x); //still outputs 'a'
f2();
console.log(x); //now outputs 'b'
在函数内部声明的变量只能从这些函数内部访问(或scoped)。如果是这样的话样本可能会更清楚:
function f1() {
var x = "Inside f1";
}
console.log(x);
将导致
ReferenceError: x is not defined
但是,如果函数的变量声明时没有 var
,那么函数就是 implicit global(要么是不好的做法,要么是遗漏了错误):
function f2() {
y = "Inside f2";
}
console.log(y);
将按您预期的方式工作,同时还声明一个隐式全局变量。
值得一提的是"use strict";
,其中运行ES5's Strict Mode. You generally want to declare this inside a function, which causes the function to be run in strict mode, and avoids the semantics of strict mode from breaking interoptability中的代码与其他代码。
function f3() {
"use strict";
z = "Inside f3";
}
console.log(z);
将导致
ReferenceError: z is not defined
因为严格模式不允许您声明隐式全局。
根据您的评论澄清,隐式全局变量将 "overwrite" 彼此。更明确地使用 JavaScript 术语:
x = 10
将在环境的全局对象x
上声明一个 属性,window.x
用于浏览器环境,global.x
用于 Node/IO 环境。x = 20
将重新定义上面讨论的 属性。
这里有一个小片段,您可以在任何环境中 运行 证明这一点。我绝不是说你应该使用隐式全局变量,而是提供另一个例子来说明你为什么不应该使用。
function functionThatNeedsGreaterThan50(value) {
// Skip checking the parameter because we trust the
// other developers on the team to make sure they call
// this right.
}
function f4() {
q = 42;
}
function f5() {
q = 62;
}
f4();
f5();
console.log(q);
// sometime thousands of calls later, one of which was
f4();
// I thought this was 62 but
functionThatNeedsGreaterThan50(q);