先看一段代码的运行结果:
console.log(foo) // foo(){ }
var foo=1;
console.log(foo) // 1
function foo(){
}
console.log(foo) //1
console.log(foo()) //TypeError:foo is not a function
为啥会这样呢?
在解释器解析js代码的过程中,有一个预编译的过程,会把需要用到的变量声明和函数声明提升到方法体的最顶部,并且还有优先顺序之分:参数>函数>变量。需要注意的是,我们平时写函数的时候有2种写法:1>函数表达式 var fn=function fn(){ }
2>函数声明式 function fn(){} ,只有第二种函数声明式才会被提升,并且函数的提升是整个函数体的提升,同时变量也是只有声明被提升了,赋值没有被提升。
所以上面这段代码可以看成是这样的:
function foo(){}
console.log(foo) //这时候打印出来的就是foo函数
var foo=1 //这时候foo被重新赋值,变成了数值1
console.log(foo) //重写后的foo是1
console.log(foo) //1,同上
console.log(foo()) //因为foo被重写后已经是个Number类型的了,所以她不是函数,就会报错啦
艾玛,刚刚看到了一个更骚的题:
var b=10;
(function b(){
b=20
console.log(b) //ƒ b(){ b=20; console.log(b) }
})()
1、IIFE(立即执行函数)中的函数是函数表达式,不是函数声明
2、IIFE的函数名只在函数内部有效,并且函数名的绑定是常量绑定
3、对于一个常量进行赋值,在strict模式下回报错,非strict模式下静默失败
所以,这里的b函数是一个相当于用const定义的常量,内部无法进行重新赋值,如果在严格模式下会报错
网友评论