函数申明提升的问题,求大神解答!!!

cantiaozi 2018-08-19 11:53:11
函数申明提升的问题,求大神解答!!!
代码:
foo();//TypeError: foo is not a function
var a = true;
if(a){
function foo(){console.log('a');}
} else {
function foo(){console.log('b');}
}
上面的代码foo();运行的时候会提示TypeError: foo is not a function。这是我不能理解的地方。
按照我的理解:函数申明会提升到所在作用域的顶部,因此这里的foo()函数的申明会出现在foo();语句的上面,同时下面的一个foo函数申明会覆盖上面一个foo函数申明,所以代码运行应该会输出“b“。但是实际与我的理解并不符合。求大神解答!
...全文
123 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
cantiaozi 2018-08-20
  • 打赏
  • 举报
回复
@天际的海浪:块级作用域不是在使用let或const的时候才有的吗?这里没有用到这两个关键字怎么会有块级作用域呢?退一步说,就算这里{}是块级作用域,无法访问foo函数,那也应该是报referenceError,而不是报TypeError呀。TypeError说明变量foo被申明,但是不是函数类型。
cantiaozi 2018-08-20
  • 打赏
  • 举报
回复
@天际的海浪,谢谢大神指点!大神厉害!
天际的海浪 2018-08-20
  • 打赏
  • 举报
回复

console.log("foo" in window);//输出true
console.log(foo); //输出undefined
foo=1;
console.log(foo);//输出1
if(1){
console.log(window.foo,foo);//输出 1 和 foo(){console.log('a');}
function foo(){console.log('a');}
console.log(window.foo,foo);//输出 foo(){console.log('a');} 和 foo(){console.log('a');}
}
if(1){
console.log(window.foo,foo);//输出 foo(){console.log('a');} 和 foo(){console.log('b');}
function foo(){console.log('b');}
}
console.log(foo);//输出 foo(){console.log('b');}
天际的海浪 2018-08-20
  • 打赏
  • 举报
回复
以前没太注意,这还真是奇怪,给我的感觉是,在Chrome里,
function foo(){}是在代码执行前先声明了一个var作用域的foo变量(这时foo没有赋值),但是声明提升却是在块作用域内提升,这样又声明了一个同名的let块作用域的foo变量。这时同时存在var作用域的foo变量和let块作用域的foo变量。
当真正执行到function foo(){}的时候才对var作用域的foo变量重新赋值。
天际的海浪 2018-08-20
  • 打赏
  • 举报
回复
函数申明会提升到所在作用域的顶部是没有错。关键是要明白函数所在的是哪个作用域?
在es5(也就是ie10以前)中,没有块作用域,两个foo()函数都在全局作用域中,就是按照你理解的会输出“b“。
但是到了es6(也就是ie11或者其它现代浏览器)中,开始有块作用域了,这样两个foo()函数就分别在两个块作用域中,申明提升也只是提升到块作用域的顶部,你在全局作用域中调用foo()函数当然是未定义。

你在if和else后面不写{},就没有块作用域了,两个foo()函数又都在全局作用域中,就是按照你理解的了。
foo();
var a = true;
if(a)
function foo(){console.log('a');}
else
function foo(){console.log('b');}

天际的海浪 2018-08-20
  • 打赏
  • 举报
回复
这是mdn上的说明

winzond 2018-08-19
  • 打赏
  • 举报
回复
引用 1 楼 winzond 的回复:
能不能这样定义:

function foo(){
  if(a){
    console.log('a');
  }else{
    console.log('b');
  }
}
我这样输出的是b,不是a
winzond 2018-08-19
  • 打赏
  • 举报
回复
能不能这样定义:

function foo(){
  if(a){
    console.log('a');
  }else{
    console.log('b');
  }
}

87,910

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧