fun(); //报错TypeError
var a=true;
if(a){
function fun() {
console.log("1");
}
}else{
function fun() {
console.log("2");
}
}
按书中的说法,由于函数的提升,且不受条件判断控制,应该是输出2的。可是我运行却报错了。
然后我把条件控制去掉,像这样:
fun();//2
function fun() {
console.log("1");
}
function fun() {
console.log("2");
}
果然,输出了2
然后,我把条件语句加上,在最后执行函数,像这样:
var a=true;
if(a){
function fun() {
console.log("1");
}
}else{
function fun() {
console.log("2");
}
}
fun();//1
输出1
谁能解释一下,第一个输出的原理?以及和书上的不一样,是因为浏览器升级了的缘故吗?
我非常同意 @theWalker 的回答。
首先是不赞成这种写法,然后我分享一下在 Node5 下的试验
所以可以分析出,最下面的
.log(3)
那个函数是函数定义,上面两个是被当作函数表达式处理的。但是命名函数表达式的名称只能在函数表达式内部使用,所以这里如果是当作命名函数表达式的话,又不科学了。再做个试验,用括号强制把中间两个函数申明为函数表达式符合对命名函数表达式的判断。
所以,目前只能是认为解释器把那句话解释成了
var fun = function fun() {....}
这种写法不太推荐,不同浏览器执行结果不太一样。
比较详细的介绍,看完应该懂了,深入理解JavaScript系列(2):揭秘命名函数表达式
ES2015 中已经增加了块级作用域,而 Chrome 已经实现了这个新版语法,所以
if
内是一个作用域。声明提前只是会提前到当前作用域的顶部,所以fun
的定义只会提前到if
内最前面,而不会影响外层的fun()
执行作用域。老语法中因为没有块级作用域,示例的整个代码都在一个作用域下,所以fun
的定义会提前到整个代码的最前面,能够影响到fun()
的执行作用域。对,浏览器升级了,Chrome 报错,Safari输出2
我测试了一下在我的
node v4.2.0
是正常的输出2
, Chrome上是会报错的.浏览器...书上说的是js标准基本是基于ECMA的,所以不同浏览器,统一浏览器不同版本都会与差异的,因为标准总是先于实现。说一,看JDKJS比较推荐在node稳定版上测试