DC_*_*DC_ 48 javascript scope function
如何处理函数声明?
var abc = '';
if(1 === 0){
function a(){
abc = 7;
}
}else if('a' === 'a'){
function a(){
abc = 19;
}
}else if('foo' === 'bar'){
function a(){
abc = 'foo';
}
}
a();
document.write(abc); //writes "foo" even though 'foo' !== 'bar'
Run Code Online (Sandbox Code Playgroud)
此示例在Chrome和Firefox中生成不同的输出.fooFF输出时输出Chrome 19.
Che*_*vel 58
当提出这个问题时,ECMAScript 5(ES5)很普遍.在ES5的严格模式下,函数声明不能嵌套在if块内,如问题所示.在非严格模式下,结果是不可预测的.不同的浏览器和引擎实现了他们自己处理块内函数声明的规则.
截至2018年,许多浏览器都支持ECMAScript 2015(ES2015),现在允许在块内部使用函数声明.在ES2015环境中,块内的函数声明将作用于该块内.问题中的代码将导致未定义的函数错误,因为该函数a仅在if语句范围内声明,因此在全局范围内不存在.
如果需要有条件地定义函数,那么应该使用函数表达式.
来自http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/
在javascript中,你有函数声明:
function foo() {
}
Run Code Online (Sandbox Code Playgroud)
和函数表达式
var foo = function() {
}
Run Code Online (Sandbox Code Playgroud)
引自http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
"函数声明和函数变量总是由JavaScript解释器移动('提升')到JavaScript范围的顶部".
所以在你的第一个例子中发生的是,函数声明function a()被提升到Javascript范围的顶部,因此产生'foo',即使if计算结果为false
可以认为var foo是一个普通的Javascript语句,它只在你的javascript的运行时执行,不像function foo(),这就是为什么以下是有效的:
alert(foo());
function foo() {
return 'gw ganteng';
}
Run Code Online (Sandbox Code Playgroud)
这里,在尝试调用之前function foo(),由解析器解析,放入foo()当前作用域alert(foo())
http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/
在JavaScript执行中,有Context(ECMA 5分为LexicalEnvironment,VariableEnvironment和ThisBinding)和Process(一组要按顺序调用的语句).输入执行范围时,声明对VariableEnvironment有贡献.它们与陈述(例如退货)不同,不受其程序规则的约束.