JavaScript中l(wèi)et與const命令使用
let命令
基本使用
let
是ES6中新增的聲明變量的命令,但是和var
不同,let
不可以被重復(fù)聲明,let
只在其命令的代碼塊內(nèi)有效,let
禁止變量出現(xiàn)變量提升現(xiàn)象,let
會通過暫時性死區(qū)的方式來避免程序上的錯誤
代碼塊:使用
{}
包括起來的內(nèi)容聲明變量:分配一個存儲空間
不可重復(fù)聲明:
let
聲明過后的變量無法再再次聲明,而var
可以重復(fù)聲明{ let a = 10; var a = 1; // 'a' has already been declared }
{ var a = 10 var a = 1 } console.log(a) // 1
不同代碼塊可被重復(fù)聲明:值得注意的是let的不可重復(fù)聲明是作用在同一代碼塊中的,后面將會具體解釋相關(guān)的概念即塊級作用域
{ let a = 1 console.log(a) } { let a = 2 console.log(a) }
有效區(qū)間的不同:
let
只在其命令的代碼塊內(nèi)有效,而var
聲明的變量可全局有效,下面例子說明兩者不同。{ let a = 10; var b = 1; } console.log(a) // a is not defined console.log(b) // 1
變量提升:之前使用
var
聲明變量,在聲明前調(diào)用為undefined
,undefined
就是我們熟悉的聲明但未賦值,這種現(xiàn)象叫做變量提升,但是let
禁止了這一行為,使用let
所聲明的變量一定需要在聲明后使用。console.log(bar) // Cannot access 'bar' before initialization let bar = 2
變量提升的編譯:我們分別來看下變量提升現(xiàn)象在編譯后的情況,就能徹底理解變量提升現(xiàn)象出現(xiàn)的原因,所有的聲明變量語句在編譯后都會將聲明語句提到程序的最先級,所以才會出現(xiàn)聲明但未賦值的現(xiàn)象。
// 編譯前 console.log(a) var a = '豬痞惡霸' // 編譯后 var a console.log(a) a = '豬痞惡霸'
暫時性死區(qū):在代碼塊中使用
let
聲明變量前,該變量不可用,這種現(xiàn)象稱為暫時性死區(qū),其實這點和變量提升有些相似,我理解為:let
禁止變量提升現(xiàn)象的原因是在聲明變量前的代碼區(qū)域為暫時性死區(qū){ // 暫時性死區(qū) tmp = 'abc'; console.log(tmp) // 暫時性死區(qū) let tmp; // 聲明tmp,結(jié)束暫時性死區(qū) console.log(tmp) // undefined 聲明未賦值 tmp = '123' console.log(tmp) // 123 }
隱蔽的死區(qū):有些暫時性死區(qū)會在我們注意不到的地方,比如
function bar(x = y, y = 2) { return [x,y] } bar() // Cannot access 'y' before initialization bar(2) // 無錯誤
由于x的默認(rèn)值為y,且y的聲明還沒開始,所以
x = y
處于死區(qū)中
適用場景
let
與var
根據(jù)其各自不同的特點有著不同的適用場景
計數(shù)器的使用:如果我們需要一個用來計數(shù)的變量,那么我們就可以使用
let
來聲明。var arr = [] for(let i = 0; i < 10; i++) { arr[i] = () => { console.log(i) } // 利用計數(shù)進(jìn)行操作 } arr[7]() // 7
for(var i = 0; i < 10; i++) { arr[i] = () => { console.log(i) } // 利用計數(shù)進(jìn)行操作 } arr[7]() // 10
根據(jù)適用
var
和let
的輸出結(jié)果就能清楚兩者的適用場景,而這也凸顯了let
聲明變量的不同之處,即聲明的有效區(qū)間不同for循環(huán)中的父子關(guān)系:
for
循環(huán)中有兩個作用域,即父作用域與子作用域,設(shè)置循環(huán)變量的部分為父作用域,循環(huán)體內(nèi)部為子作用域for(let i = 0; i < 3; i++) { let i = 'abc'; console.log(i) } // abc // abc // abc
上面的例子循環(huán)打出了三個
abc
就說明了兩個i的作用域不同,如果不在循環(huán)體內(nèi)聲明的話將會打印出0,1,2
塊級作用域
ES6新增了塊級作用域,此前ES5只有全局作用域與函數(shù)作用域
- 全局作用域:擁有全局作用域的變量可以在程序的任意位置訪問,而window對象的所有屬性都具有全局作用域。
- 函數(shù)作用域:又被稱為局部作用域,每一個函數(shù)中都有一個函數(shù)作用域或者嵌套更多的函數(shù)作用域,在函數(shù)作用域中定義的變量只能在該函數(shù)作用域內(nèi)部使用。
概念
塊級作用域的出現(xiàn)其實是由新增聲明let
產(chǎn)生的
let n = 5 function fn() { if(true) { let n = 10 } console.log(n) } fn() // 5
上面的例子詮釋了塊級作用域的作用,即外層代碼塊不受內(nèi)層代碼塊的影響,我們在if
函數(shù)體內(nèi)聲明的n
只有在if
函數(shù)體內(nèi)可以訪問,而fn
中訪問n
不受if
內(nèi)層的聲明影響。
存在意義
var tmp = new Date(); function fn() { console.log(tmp); if(false) { var tmp = 'hello world' } } fn()
如上,存在函數(shù)作用域與全局作用域,正常情況下fn()
函數(shù)體內(nèi)if
函數(shù)體外是使用外層即var tmp = new Date();
但是由于變量提升現(xiàn)象的存在即if
函數(shù)體內(nèi)的var tmp = 'hello world'
發(fā)生了變量提升,即fn()
函數(shù)體內(nèi)的編譯形式如下,所以輸出結(jié)果為undefined
。
function fn() { var tmp console.log(tmp); tmp = 'hello world' }
而塊級作用域正是解決了這個問題
let n = 5 function fn() { if(true) { let n = 10 } console.log(n) } fn() // 5
除此之外還可以防止局部作用域變量的泄露到全局當(dāng)中
let arr = [1,2,3] for(var i = 0; i < arr.length; i++) { console.log(arr[i]) } { console.log(i) // 3 }
如上就造成了變量泄露,i
變量被泄露到了全局當(dāng)中,那么我們使用塊級作用域來看一看i is not defined
,說明變量未被泄露到全局中。
let arr = [1,2,3] for(let i = 0; i < arr.length; i++) { console.log(arr[i]) } console.log(i) // i is not defined
const命令
基本使用
const
聲明的變量無法被再次賦值改變,且聲明的時候必須賦值
const name = '豬痞惡霸' name = 'fzf404' // Assignment to constant variable.
const name // Missing initializer in const declaration name = '豬痞惡霸'
const
與let
的特性很像,比如只在其聲明的塊級作用域內(nèi)有效,存在暫時性死區(qū)
不可被const的情況
javascript中有兩種數(shù)據(jù)類型即:簡單數(shù)據(jù)類型,復(fù)雜數(shù)據(jù)類型
簡單數(shù)據(jù)類型:數(shù)值,字符串,布爾值
復(fù)雜數(shù)據(jù)類型:數(shù)組,對象
引出數(shù)據(jù)類型的原因正是因為兩種數(shù)據(jù)類型的訪問方式不同,簡單數(shù)據(jù)類型的值直接保存變量所指向的內(nèi)存地址,直接訪問就可以拿到值而復(fù)雜數(shù)據(jù)類型的訪問是通過變量指向的內(nèi)存地址,內(nèi)存地址保存的是另一個指針(引用)
const
聲明是通過保證變量所指向的那個內(nèi)存地址不能改動,所有說使用const
聲明復(fù)雜數(shù)據(jù)類型,會出現(xiàn)數(shù)組的元素和對象的屬性可以發(fā)生改變
const person = {} person.name = "豬痞惡霸" console.log(person.name) // 豬痞惡霸
如果我們想要使我們的對象不可以發(fā)生改變那么我們可以使用Object.freeze
方法,詳細(xì)使用參考這篇文章:凍結(jié)JS對象方法技術(shù)詳解
到此這篇關(guān)于JavaScript中l(wèi)et與const命令使用的文章就介紹到這了,更多相關(guān)JavaScript let與const命令內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaScript中const、var和let區(qū)別淺析
- JavaScript ES6中const、let與var的對比詳解
- JavaScript變量聲明var,let.const及區(qū)別淺析
- 了解javascript中l(wèi)et和var及const關(guān)鍵字的區(qū)別
- JavaScript中var、let、const區(qū)別淺析
- javascript的var與let,const之間的區(qū)別詳解
- JavaScript?ES6語法中l(wèi)et,const?,var?的區(qū)別
- 面試官常問之說說js中var、let、const的區(qū)別
- javascript?變量聲明?var,let,const?的區(qū)別
相關(guān)文章
微信實現(xiàn)自動跳轉(zhuǎn)到用其他瀏覽器打開指定APP下載
這篇文章主要介紹了微信實現(xiàn)自動跳轉(zhuǎn)到用其他瀏覽器打開指定APP下載,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-02-02Js使用WScript.Shell對象執(zhí)行.bat文件和cmd命令
這篇文章主要介紹了Js使用WScript.Shell對象執(zhí)行.bat文件和cmd命令,需要的朋友可以參考下2014-12-12淺談js函數(shù)中的實例對象、類對象、局部變量(局部函數(shù))
下面小編就為大家?guī)硪黄獪\談js函數(shù)中的實例對象、類對象、局部變量(局部函數(shù))。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11httpclient模擬登陸具體實現(xiàn)(使用js設(shè)置cookie)
最簡單的方法就是通過得到的cookie定制一個httpclient,感興趣的朋友可以了解下本文2013-12-12