首先说明,本文的置前说的是解析器自动将函数或者变量的申明放到了该作用域的最前面。由于 JavaScript属于C类语言,先申明、后定义、再使用的顺序规则自然也是正确的,只是由于js解析器特殊原因,致使出现了可以先使用再定义的错觉,其实是js解析器搞的鬼。
- 变量申明置前
首先来代码。
(function() {
// Outputs: undefined
console.log(declaredLater);
var declaredLater = "Now it's defined!";
// Outputs: "Now it's defined!"
console.log(declaredLater);
})();
能够不报错,只是说了个undefined,说明确实declaredLater 变量放到了前面。
- 函数申明置前
这个就有点坑了,一个分号可以害死人的,其实还是要考察各位的C语言的语法功底。不说了,上代码。
// Outputs: "Definition hoisted!"
definitionHoisted();
// TypeError: undefined is not a function
definitionNotHoisted();
function definitionHoisted() {
console.log("Definition hoisted!");
}
var definitionNotHoisted = function () {
console.log("Definition not hoisted!");
};
很明显看出,definitionHoisted函数体后面是没有分号的,这中情况其实是大家最愿意看见的(因为和自己以前学的C类语言没啥两样嘛),其实解析器仅将该函数的申明和定义都置前了,所以调用没问题;但是definitionNotHoisted 函数体后面有分号的,这就回到了变量的那种置前的情况,其实是解析器将该函数的申明都置前了,函数的定义并未置前,而一个变量申明后默认都是undefined,并且undefined 又不是一个函数,所以会出现 undefined is not a function的错误。