JS中变量会预解析,所谓的预解析就是:在当前作用域中,JavaScript代码执行之前,浏览器首先会默认的把所有带var和function声明的变量进行提前的声明或者定义。
编译前:
console.log(a);
var a = 3;
编译后可看做:
var a; // 将变量a的声明提升至最顶端,赋值逻辑不提升。 console.log(a); // undefined a = 3; // 代码执行到原位置即执行原赋值逻辑
一、变量声明的提升是以变量所处的第一层词法作用域为“单位”的,即全局作用域中声明的变量会提升至全局最顶层,函数内声明的变量只会提升至该函数作用域最顶层。
编译前:
console.log(a); var a = "a"; var foo = () => { console.log(a); var a = "a1"; } foo()
编译后可看做:
var a; console.log(a); // undefined a = "a"; var foo = () => { var a; // 全局变量会被局部作用域中的同名变量覆盖 console.log(a); // undefined a = "a1"; }
二、函数声明的优先级高于变量声明。
三、函数提升只会提升函数声明,而不会提升函数表达式。
编译前:
console.log(foo1); foo1(); console.log(foo2); foo2(); function foo1() { console.log("foo1"); }; var foo2 = function () { console.log("foo2"); }
编译后可看做:
function foo1() { console.log("foo1"); }; var foo2; console.log(foo1);// [Function: foo1] foo1(); // foo1 console.log(foo2); // undefined foo2(); // TypeError: foo2 is not a function foo2 = function () { console.log("foo2"); }