var、let抬纸、const相關問題
- 1咙俩,var
- 2,let
- 3湿故,const
- 4阿趁,塊級作用域
- 5,三者區(qū)別
- 6坛猪,const 定義的變量可以修改嗎脖阵?
- 7,經(jīng)典面試題
1墅茉,var
1, 聲明提升
console.log(num) // undefined
var num = 100
2, 變量覆蓋
var num1 = 100
var num1 = 200
conosle.log(num1) // 200
3, 沒有塊級作用域
function fn() {
for (var i = 0; i <= 5; i++) {
console.log(i) // 0 1 2 3 4 5
}
console.log(i) // 6
}
fn()
2命黔,let
1, let 聲明的變量具有塊級作用域的特征
function fn() {
let a = 10
}
console.log(a) // a is not defined
2, 在同一個塊級作用域,不能重復聲明變量
function fn() {
let a = 10
let a = 20
}
console.log(a) // Identifier 'a' has already been declared
3, let 聲明的變量不存在變量提升就斤,換種說法就是let聲明存在暫時性死區(qū)(TDZ)
console.log(num) // Cannot access 'num' before initialization
let num = 10
3移宅,const
1, const 聲明的變量具有塊級作用域的特征
function fn() {
const a = 10
}
console.log(a) // a is not defined
2, 在同一個塊級作用域起愈,不能重復聲明變量
function fn() {
const a = 10
const a = 20
}
console.log(a) // Identifier 'a' has already been declared
3, const 聲明的變量不存在變量提升幸撕,換種說法就是const聲明存在暫時性死區(qū)(TDZ)
console.log(num) // Cannot access 'num' before initialization
const num = 10
4, const 聲明一旦定義后奸鬓,不能修改
const num = 100
num = 200
console.log(num) // Assignment to constant variable.
4濒析,塊級作用域
ES5中作用域有:全局作用域月匣、函數(shù)作用域承边,沒有塊級作用域的概念掖蛤。
ES6新增了塊級作用域,由 {} 包括刁标,if 語句和 for 語句里面的 {} 都屬于塊作用域
{
var num = 100
console.log(num) // 100
}
console.log(num) // 100 可見颠通,通過var定義的變量可以跨塊作用域訪問到
function fn() {
var num = 100
console.log(num) // 100
}
console.log(num) // num is not defined 可見,通過var定義的變量不能跨函數(shù)作用域訪問到
if (true) {
var num = 100
}
console.log(num) // 100
for (var i = 0; i <= 5; i++) {
var num = 100
}
console.log(i) // 6
console.log(num) // 100
if 語句和 for 語句中用 var 定義的變量可以在外面訪問到膀懈,可見顿锰,if 語句和 for 語句屬于塊級作用域,不屬于函數(shù)作用域
5启搂,三者區(qū)別
- var 定義的變量硼控,沒有塊的概念,可以跨塊訪問, 不能跨函數(shù)訪問
- let 定義的變量胳赌,只能在塊作用域里訪問牢撼,不能跨塊訪問,也不能跨函數(shù)訪問
- const 用來定義常量疑苫,使用時必須初始化(即必須賦值)熏版,只能在塊作用域里訪問,且不能修改
// 塊級作用域
{
var a = 100
var b = 200
var c = 300
var a1
let b1
// const c1
console.log(a) // 100
console.log(b) // 200
console.log(c) // 300
console.log(a1) // undefined
console.log(b1) // undefined
}
console.log(a) // 100
console.log(b) // 200
console.log(c) // 300
// 函數(shù)作用域
(function fn() {
var a = 100
let b = 200
const c = 300
console.log(a) // 100
console.log(b) // 200
console.log(c) // 300
})()
console.log(a) // a is not defined
console.log(b) // b is not defined
console.log(c) // c is not defined
6捍掺,const 定義的變量可以修改嗎撼短?
const 定義的基本類型不能改變,但是定義的對象是可以通過修改對象屬性等方法改變的
const num = 100
num = 200
console.log(num) // Assignment to constant variable.
const person = {
name: 'Tom',
age: 18
}
person = {
name: 'Jerry',
age: 20
}
console.log(person) // Assignment to constant variable.
const person = {
name: 'Tom',
age: 18
}
person.name = 'Jerry'
console.log(person) // {name: 'Jerry', age: 18}
基本數(shù)據(jù)類型的變量保存在棧區(qū)中挺勿,基本數(shù)據(jù)類型的值直接在棧內(nèi)存中存儲曲横,值與值之間是獨立存在的,修改一個變量不會影響其他的變量不瓶。
引用數(shù)據(jù)類型的值是同時保存在棧內(nèi)存和堆內(nèi)存的對象禾嫉,棧區(qū)保存了對象在堆區(qū)的地址。
const 聲明的 person 給屬性重新賦值是可以的湃番,但是給 person 重新賦值是不可以的夭织,那樣會改變 person 在棧區(qū)的地址
7,經(jīng)典面試題
for (var i = 0; i <= 5; i++) {
setTimeout(function() {
console.log(i)
}, 1000)
}
console.log(i)
setTimeout 是異步執(zhí)行的吠撮,1000ms后向任務隊列里添加一個任務尊惰,只有主線程的全部執(zhí)行完才會執(zhí)行任務隊列里的任務,所以當主線程 for 循環(huán)執(zhí)行完之后 i 的值為 6泥兰, 這時候再去執(zhí)行任務隊列里執(zhí)行任務弄屡, i 全部是 6。
每次 for 循環(huán)的時候 setTimeout 都會執(zhí)行鞋诗,但是里面的 function 則不會執(zhí)行被放入任務隊列膀捷,因此放了 6 次, for 循環(huán)的 6 次執(zhí)行完之后不到 1000ms削彬, 100ms后全部執(zhí)行任務隊列里的函數(shù)全庸,所以輸出 6 個 6秀仲。
for (let i = 0; i <= 5; i++) {
setTimeout(function() {
console.log(i)
}, 1000)
}
console.log(i)
let定義的 i 事塊級作用域,每個 i 只能存活到大括號結(jié)束壶笼,并不會把后面的 for 循環(huán)的 i 值賦給前面的 setTimeout 中的 i神僵,而var 定義的 i是局部變量,這個 i 的生命周期不受for 循環(huán)的大括號限制覆劈。