?? 個人主頁歡迎訪問 ??
大家好,本人名叫蘇日儷格站玄,大家叫我 (格格) 就好枚驻,在上一章節(jié)中我們了解到一些關(guān)于ES6的知識,下面我們一起來繼續(xù)學(xué)習(xí)ES6的新特性let和const:
let和const都是定義(聲明)用的株旷,let是聲明變量再登,而const是聲明常量的;
變量:定義完了可以改變
常量:定義完了無法改變
var雖然也是聲明變量的晾剖,不過var聲明有很多潛在的問題锉矢,至于是哪些問題,讓我們來看一個例子:
for (var i=0; i<10; i++) {
//coding
}
alert(i); // i=10
小白:⊙⊙這不科學(xué)啊齿尽,在外面還能訪問沽损?
格格:這個時候有的朋友看了就感覺很神奇,尤其是學(xué)Java的循头,不應(yīng)該是這樣的對吧绵估,但事實如此,接著往下看你就明白了
如果非得說到作用域的問題的話卡骂,那么有兩種作用域国裳,一個是全局作用域,另一個就是函數(shù)作用域(局部作用域)全跨,在這個例子里面聲明的i就是一個全局的變量缝左,所以下面是可以訪問到的,如果下文繼續(xù)使用i的話浓若,那么就要從i=10開始渺杉,后果不堪設(shè)想。
下面我們再來看一個例子:
var a = 1;
function test(){
alert(a); // a = undefined
var a = 2;
}
test();
這個例子暴露了一個問題挪钓,其實也不算是問題是越,就是因為JavaScript具有自己的特性:變量提升的問題和預(yù)解析的問題,這到底是個什么東西呢碌上?上面的例子可以也看成是下面的例子:
var a = 1;
function test(){
var a;
alert(a);
a = 2;
}
test();
相信大家已經(jīng)看懂了英妓,在代碼執(zhí)行的過程中挽放,事先定義了一個a,這時并沒有賦值蔓纠,a當(dāng)然就是undefined辑畦;
由此我們給出一個定義:變量提升意思就是在js執(zhí)行之前,會把變量提到頂部腿倚,而且不會突破作用域纯出;再看一下預(yù)解析的例子:
<script type="text/javascript">
var a = 1;
</script>
<script type="text/javascript">
alert(a); // a = 1
</script>
JavaScript雖然是一個腳本語言,無需解析敷燎,但是它還是有一個小小的預(yù)解析的過程:
讀取一個script標(biāo)簽 ==> 預(yù)解析 ==> 執(zhí)行代碼 ==> 再讀取下一個script標(biāo)簽 ==> ...依次循環(huán)
下面讓我們回到let和const:
for (let i=0; i<10; i++) {
//coding...
}
alert(i); // i is not defined
大家可以看到暂筝,同樣的例子使用let定義i的話,外面調(diào)用就會報錯硬贯,那么這又是因為什么呢焕襟?
這就是ES6中引入的新特性:塊級作用域
塊級作用域就是{ coding... }
只要是帶有{}的都是一個塊級作用域,下面到了考察大家的時刻了:
let a = 1;
function test(){
alert(a);
let a = 2;
}
test();
和之前的例子一樣饭豹,只不過將var換成了let鸵赖,這個時候的結(jié)果就是a is not defined,因為let只在塊級作用域中起作用拄衰,所以a不可能是1它褪,由于let不能提升,所以a就是未定義翘悉。
綜上所述:let的第一個特性就是不存在變量提升
小白:什么鬼茫打?什么叫做第一個特性,難道還有第二個特性不成 ?妖混?
格格:那么我要在這里恭喜你中了大獎了老赤,回家準(zhǔn)備買彩票吧,它確實有第二個特性<( ̄ˇ ̄)/
下面在讓我們一起看一個例子:
let a = 1;
let a = 2;
alert(a);
這個時候你會發(fā)現(xiàn)制市,它和var是有著非常大的區(qū)別的诗越,正常使用var的時候大家都知道,a肯定是等于2的息堂,那么在這里Identifier 'a' has already been declared,這句話的意思是a已經(jīng)被定義了块促,也就是說let不允許重復(fù)定義同一個變量
格格:這就是它的第二個特性了荣堰,接來下我們要講的就是let的第三個特性?(′?)?
小白:什么?o( ̄ヘ ̄o#) 還有第三個竭翠?
格格:其實第三個即是第二個振坚,第二個即是第三個つ﹏?
下面我們來看一個例子:
for (let i=0; i<10; i++) {
let i = 2;
console.log(i);
}
小白:so easy!i已經(jīng)被定義了唄
格格:嘿嘿斋扰,被忽悠了吧渡八,答案是輸出了10個2
小白:(???*) 為啥子嘛
剛才說到啃洋,不允許重復(fù)定義一個變量,但它的條件肯定是建立在塊級作用域下的呀屎鳍,這個循環(huán)中的i是作用域里面的i的父級宏娄,所以在里面還是可以定義的,第三個特性就算是給第二個加個補(bǔ)充:在不同作用域下逮壁,可以重復(fù)定義
小白:噢噢孵坚,剛才好像被晃了一下子→_→
格格:ㄟ( ▔, ▔ )ㄏ
const的特性和let是一模一樣的,不同的就只是常量而已窥淆,即為定義完了不能修改卖宠,否則報錯
下面又到了考察大家的時刻了:
const arr = ['aaa','bbb','ccc'];
arr.push('ddd');
console.log(arr); // ["aaa", "bbb", "ccc", "ddd"]
小白:說好的不能修改了?你在逗我忧饭。扛伍。。
格格:哈哈词裤,你又不懂了吧
為什么會這樣刺洒?下面引用大神阮一峰的ECMAScript 6 入門
const實際上保證的,并不是變量的值不得改動亚斋,而是變量指向的那個內(nèi)存地址所保存的數(shù)據(jù)不得改動作媚。對于簡單類型的數(shù)據(jù)(數(shù)值、字符串帅刊、布爾值)纸泡,值就保存在變量指向的那個內(nèi)存地址,因此等同于常量赖瞒。但對于復(fù)合類型的數(shù)據(jù)(主要是對象和數(shù)組)女揭,變量指向的內(nèi)存地址,保存的只是一個指向?qū)嶋H數(shù)據(jù)的指針栏饮,const只能保證這個指針是固定的(即總是指向另一個固定的地址)吧兔,至于它指向的數(shù)據(jù)結(jié)構(gòu)是不是可變的,就完全不能控制了袍嬉。因此境蔼,將一個對象聲明為常量必須非常小心。
這個arr是一個數(shù)組伺通,即是一個對象箍土,對象本身是存在引用的,如果想讓數(shù)組無法修改的話罐监,也有辦法的吴藻,可以用Object.freeze(對象)
格格:所以呀,var就當(dāng)做是你的前任弓柱,忘了吧...
小白:哪能說忘就忘沟堡,相信自己會慢慢接受現(xiàn)任的
關(guān)于let侧但、const我們都已經(jīng)了然于心,預(yù)知解構(gòu)賦值如何航罗,請聽下回分解 (^?^)/~~~
本文的所有內(nèi)容均是一字一句敲上去的禀横,希望大家閱讀完本文可以有所收獲,因為能力有限伤哺,掌握的知識也是不夠全面燕侠,歡迎大家提出來一起分享!謝謝O(∩_∩)O~
歡迎來我的GitHub立莉,喜歡的可以star绢彤,項目隨意fork,支持轉(zhuǎn)載但要下標(biāo)注蜓耻,同時恭候:我的博客 Resume