JS代码的执行是由浏览器中的js解析器来执行的,js解析器执行js代码的时候,分为两个过程分为预解析过程和代码执行过程。
1.预解析
直接看代码?
console.log(a);// undefined
var a = 10;
function f() {
console.log(b);
var b = 20;
}
f();// undefined
正常理解,JS代码是顺序执行,console.log(a)输出变量a的时候,a变量并未声明,此时输出a应报错才对,同理f函数中输出变量b时b并未声明,也应该报错才对,但实际输出undefined并未报错。上面这段代码和下面这段代码等同:
var a;
console.log(a);// undefined
a = 10;
function f() {
var b;
console.log(b);
b = 20;
}
f();// undefined
由此可见JS的预解析将变量的声明进行了提升。其实JS预解析也会将函数的定义进行提示。
f1();// 未报错,输出f函数被调用
function f1() {
console.log("f函数被调用");
}
和下面代码等同:
function f1() {
console.log("f函数被调用");
}
f1();// f函数被调用
2.预解析提升位置
function f() {
console.log(c);// undefined
var c = 30;
}
console.log(c);// 报错
变量的提升只会在当前的作用域中提升,提前到当前作用域的最上面。函数中的变量只会提升到函数作用域中的的最前面。
函数表达式预解析提升问题:
f();// 报错
var f = function () {
console.log("匿名函数被调用");
};
//和下面等同
var f;
f();// 报错
f = function () {
console.log("匿名函数被调用");
};
此时会报错,f is not a function,这是因为函数表达式的写法其实是变量的赋值,不是一个函数的定义,预解析只会提升var f的声明,而f=funfunction(){…};是变量的赋值不会提升,所以报错。
你我都在努力!