声明提前机制
在JavaScript存在着这样一种预处理机制,即浏览器在解析JS代码时会将var声明的变量和function声明的函数提升到当前作用域的顶部。但是解析JS代码时对var和function关键字声明的对象的处理是不一样的:前者在解析时只是将声明提前了,但是赋值却依旧在原来的位置。而后者不仅将声明提前了,而且将定义也完成。具体请看下面的例子:
console.log(hello); //undefined
sayHi(); //hi var hello = "hello";
console.log(hello); //hello function sayHi() {
console.log("hi");
}
在第一行输出一个在下面用var声明并且赋值的hello变量,没有报错但是输出的是undefined,说明hello变量的声明确实是被提前了但是没有赋值,所以输出的是undefined。正是因为给变量赋值依旧在原来的位置,所以第五行输出hello变量可以正常输出。在处理function定义的sayHi函数时,sayHi的声明被提前了,同时也对它进行了定义,所以在第二行调用sayHi时正常输出hi而不是报 sayHi is not defined 或者sayHi is not a function的错。
函数声明优先于变量声明
需要注意的是:函数声明优先于变量声明,看下面例子:
console.log(sayHi); // ƒ sayHi() { console.log("hi"); } var sayHi = "sayHi";
function sayHi() {
console.log("hi");
} console.log(sayHi); // sayHi
先用var声明变量sayHi并赋值为"sayHi",然后用function再将sayHi重新声明为一个函数。在声明的前后输出sayHi,发现前面输出的是一个函数,后面输出的是一个字符串"sayHi"。显然可以看出函数声明是优先于变量声明的。
这篇博客正好也解释了我之前写的一篇函数声明与函数表达式的区别,感兴趣的可以去看一下。