什么是變量提升?
JavaScript 中,函數(shù)及變量的聲明都將被提升到函數(shù)的最頂部。
JavaScript 中,變量可以在使用后聲明,也就是變量可以先使用再聲明。
一)var聲明變量存在變量提升,let和const不存在變量提升
console.log(a); // undefined ===> a已聲明還沒賦值,默認(rèn)得到undefined值
var a = 100;
console.log(b); // 報(bào)錯:b is not defined ===> 找不到b這個變量
let b = 10;
console.log(c); // 報(bào)錯:c is not defined ===> 找不到c這個變量
const c = 10;
再來看這段代碼
function fn() {
//var a
if (true) {
console.log(a + ' now')
}
else {
var a = 1
console.log(2)
}
}
fn() // a -> undefined
我們發(fā)現(xiàn)不執(zhí)行的代碼也會影響會執(zhí)行的代碼,因?yàn)関ar a會提升到if語句的前面
undefined可以翻譯為不明確,not defined可以翻譯為未定義
在Java中變量的分為全局變量(成員變量)或者局部變量,在方法體中定義的變量都是局部變量,否則是全局變量(即在方法體外,在類中定義的變量)
在JavaScript中,在方法體外外用var定義的變量其它方法可以共享,在方法中用var定義的變量只有該方法內(nèi)生效。
二)let、const都是塊級局部變量
顧名思義,就是只在當(dāng)前代碼塊起作用
{
let a = 1
}
console.log(a) // undefined
const 的特性和 let 完全一樣,不同的只是
1)聲明時候必須賦值
const a
編譯器報(bào)錯
控制臺報(bào)錯
SyntaxError: Missing initializer in const declaration
2)只能進(jìn)行一次賦值,即聲明后不能再修改
const a=1
a=2
編譯器報(bào)錯
控制臺報(bào)錯
TypeError: Assignment to constant variable.
3)如果聲明的是復(fù)合類型數(shù)據(jù),可以修改其屬性
三)同一作用域下let和const不能聲明同名變量,而var可以
const a =2
const a=1
SyntaxError: Identifier 'b' has already been declared
面試題
簡單的Demo
for (let i = 0; i < 5; i++) {
console.log(i)
}
上面的代碼我們知道打印結(jié)果是 0, 1, 2, 3, 4,但是你們有沒有想過這個變量i的作用域到底是什么呢?
有人說在這個for循環(huán)里呀,但是我這里想說的是這個i作用域是在括號()里。正常的代碼是這樣的:
1.首先這個變量_i的作用域是在()里才有效的,循環(huán)體里是不能訪問到_i的
2.每次循環(huán)的時候創(chuàng)建一個i變量,將括號里的_i賦值到變量i上
3.最后i++后再將變量i的值賦值回_i上
當(dāng)然這個過程是很復(fù)雜的,可以用下面代碼理解,但是JS的實(shí)現(xiàn)機(jī)制是很復(fù)雜的,這里想要說明的let i的作用域有時候并不是我們所理解的那樣的。
for (let _i = 0; i < 5; i++) {
let i = _i
console.log(i)
// i++ 先做
_i = i
}