變量提升
JavaScript 引擎的工作方式是黑竞,先解析代碼捕发,獲取所有被聲明的變量,然后再一行一行地運(yùn)行很魂。這造成的結(jié)果扎酷,就是所有的變量的聲明語句,都會被提升到代碼的頭部遏匆,這就叫做變量提升(hoisting)法挨。
console.log(a); // undefined
var a = 1;
等價(jià)于
var a;
console.log(a);
a = 1;
冷知識:let變量也會提升。但是不允許在賦值之前使用幅聘。比如:
let a = 1 { a = 2; let a; }
會報(bào)錯(cuò)凡纳。如果沒有提升,a=2
應(yīng)該將外面的a賦值為2帝蒿。
函數(shù)名提升
同理
f(); // 1
function f() {
console.log(1)
}
但是荐糜,如果采用賦值語句定義函數(shù),JavaScript 就會報(bào)錯(cuò)陵叽。
f(); // Uncaught ReferenceError: fun is not defined
let f = function() {
console.log(1)
}
此時(shí)狞尔,函數(shù)等價(jià)于
var f;
f();
f = function () {};
如果同一個(gè)函數(shù)被多次聲明,后面的聲明就會覆蓋前面的聲明巩掺。
function f() {
console.log(1);
}
f() // 2
function f() {
console.log(2);
}
f() // 2
如果同時(shí)采用function命令和賦值語句聲明同一個(gè)函數(shù)偏序,最后總是采用賦值語句的定義。但是在賦值語句前采用的是function命令胖替。
f() // 2
var f = function () {
console.log('1');
}
f() // 1
function f() {
console.log('2');
}
f() // 1
函數(shù)內(nèi)部的變量提升
函數(shù)作用域內(nèi)部也會產(chǎn)生“變量提升”現(xiàn)象研儒。不管在什么位置命令聲明的變量豫缨,變量聲明都會被提升到函數(shù)體的頭部。
function foo(x) {
if (x > 100) {
var tmp = x - 100;
}
}
等價(jià)于
function foo(x) {
var tmp;
if (x > 100) {
tmp = x - 100;
};
}
注:let聲明的變量同上文一樣