js中有三種聲明變量的方式,那他們有什么區(qū)別和相同點呢究西?
(一) let與var的區(qū)別窗慎?
let 為 ES6 新添加申明變量的命令,它類似于 var怔揩,但是有以下不同:
var 聲明的變量捉邢,其作用域為該語句所在的函數(shù)內(nèi),且存在變量提升現(xiàn)象
let 聲明的變量商膊,其作用域為該語句所在的代碼塊內(nèi)伏伐,不存在變量提升(var沒有塊級作用域,let有塊級作用域)
做同一個作用域下var 可以重復聲明晕拆,let 不允許重復聲明.
在瀏覽器中全局作用域下 var 聲明的變量自動變?yōu)闉閣indow的屬性藐翎,let聲明的變量不是window的屬性
相同點
- var 和let 聲明的變量都可以重新賦值
- 他們都可以只初始化 ,不賦值
那為什么var 可以重復聲明呢实幕?
var a = 2
var a = 3 //這樣重新賦值吝镣,不會報錯,但不推薦
當我們執(zhí)行代碼時昆庇,我們可以簡單的理解為新變量分配一塊兒內(nèi)存末贾,命名為a,并賦值為2整吆,但在運行的時候編譯器與引擎還會進行兩項額外的操作:判斷變量是否已經(jīng)聲明:
- 首先編譯器對代碼進行分析拆解拱撵,從左至右遇見var a,則編譯器會詢問作用域是否已經(jīng)存在叫 a 的變量了表蝙,如果不存在拴测,則招呼作用域聲明一個新的變量a,若已經(jīng)存在府蛇,則忽略var 繼續(xù)向下編譯集索,這時a = 2被編譯成可執(zhí)行的代碼供引擎使用。
引擎遇見 var a=3 時同樣會詢問在當前的作用域下是否有變量a,若存在务荆,則將a賦值為 3 - 由于第一步編譯器忽略了重復聲明的var妆距,且作用域中已經(jīng)有a,所以重復聲明會發(fā)生值得覆蓋而并不會報錯)函匕。若不存在毅厚,則順著作用域鏈向上查找,若最終找到了變量a則將其賦值2浦箱,若沒有找到,則招呼作用域聲明一個變量a并賦值為2祠锣。
(二)const 和var和 let的區(qū)別
- const聲明一個常量酷窥,賦值后不可更改
- const必須在聲明時候初始化,也就是聲明的時候必須賦值
- 如果const聲明的是一個對象 或者數(shù)組伴网,可以重新對他們的屬性(方法)蓬推,進行賦值
對象重新賦值
// 創(chuàng)建常量對象
const car = {type:"Fiat", model:"500", color:"white"};
// 修改屬性:
car.color = "red";
// 添加屬性
car.owner = "Johnson";
數(shù)組重新賦值方法
/ 創(chuàng)建常量數(shù)組
const cars = ["Saab", "Volvo", "BMW"];
// 修改元素
cars[0] = "Toyota";
// 添加元素
cars.push("Audi");
總結
三種聲明變量的方式,有各自的優(yōu)點和特色澡腾,具體看情況使用他們沸伏,可以讓你的代碼更簡潔高效。