根据JS预解析 以下代码为什么会报一个Uncaught TypeError: test is not a function 这样的错误呢?
test();
if(true) {
function test() {
alert('javascript')
}
}else{
function test(){
alert('node.js')
};
}
我原本是认为根据JS预解析, 函数声明不是会被提升吗? 是因为{ } 大括号的原因不能被提升到作用域的顶部吗?
也就是根据函数声明提升的话 应该是如下形式呀
function test() {
alert('javascript')
}
function test(){
alert('node.js')
};
test();//会正常的输出node.js , 而前面那个函数被覆盖
if(true) {
}else{
}
但是换成以下代码会正常输出
if(true) {
function test() {
alert('javascript')
}
}else{
function test(){
alert('node.js')
};
}
test();
但结果好像不是这样推理! 求大神解答 谢谢!!!
是因为{ } 大括号的原因不能被提升到作用域的顶部吗?
答:对
if(true) {
test();
function test() {
alert('javascript')
}
}else{
function test(){
alert('node.js')
};
}
// 输出 javascript
这么写你就明白了
其实和提升作用域没什么关系,当然可以这样理解,本质是编译时和运行时的关系,编译永远大于运行。
在 ES2015 以前,块里面的函数声明是会提升到作用域顶层的
test();
if(true) {
function test() {
alert('javascript')
}
}else{
function test(){
alert('node.js')
};
}
这段代码如果放在旧版本浏览器中运行效果如你所想
在 ES2015 之后由于增加了块级作用域,这段代码的语义有点不一样了
在块里面的函数声明语义有点类似于 let
,但是会将标识符(就是函数名)提升到作用域顶层,而函数只会提升到块的顶层
大致运行效果类似如下
var test
test()
if(true) {
test = function() {
alert('javascript')
}
}else{
test = function() {
alert('node.js')
}
}
反正严格模式禁止在块中使用函数声明的语法,这个东西就当作是糟粕就可以了