<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們都知道let命令是用來宣告變數的,類似於var,但是通過let命令宣告的變數只在所在程式碼塊內有效。
let a = []; for (let i = 0;i < 10; i++ ) { a[i] = function () { console.log(i); } } a[5](); // 5
如上程式碼所示,使用的是let宣告的i,那麼這個變數僅在塊級作用域內有效,即只在每輪迴圈內有效,所以每次迴圈的i其實都是一個新變數,所以最後輸出了5。
如果使用了var去申明i,那麼這個i是在全域性範圍內都有效的,函數陣列裡的i都會指向同一個i,匯出最後輸出的是最後一輪迴圈的i的值。
那就有了一個疑問,使用let宣告的i如果每一輪都是一個新變數,那怎麼知道上一輪迴圈的值然後計算出本輪的值?
這是因為JavaScript引擎內部會記住上一輪迴圈的值,初始化當次迴圈的i時,會在上一輪迴圈的基礎上計算。
for迴圈還有一個特別的地方,就是設定迴圈變數的括號內是一個父作用域,而回圈體內是一個單獨的子作用域。
不存在變數提升:
不存在變數提升我們應該都知道,在var命令中會發生“變數提升”,就是變數可以在宣告之前使用,而值是undefined。這種是比較奇怪的現象,因為他都還沒宣告怎麼就可以使用呢?
所以。let命令改變了這種語法,通過let宣告的變數一定要在變數宣告後才能用,不然就會報錯。
console.log(b) // undefined console.log(a) // 報錯ReferenceError let a = 2; var b = 1;
只要塊級作用域記憶體在Let命令,那麼這個let宣告的變數就係結了這個區域,不會受到外部的影響。
var num = 1; if(true) { num = 2; // 報錯,ReferenceError let num; }
如上面程式碼所示,if程式碼塊內想要修改的是if外部的num,但是if內部通過let宣告了一個num但為賦值,所以導致了通過let宣告的num繫結了這個塊級作用域(即if內部這個塊級作用域),所以不會受到外部的num影響,所以對num賦值會報錯。
ES6明確規定了,如果在區塊記憶體在let和const命令,那麼這個區塊對這些命令宣告的變數從一開始就形成封閉的作用域,只要在宣告之前就使用這些變數,就會報做。也稱暫時性死區(temporal dead zone,簡稱TDZ)
當然,這也造成了typeof變得不安全了,因為如果一個變數沒有宣告就使用typeof不會報錯,會返回一個undefined,但是現在不成立了,因為會報錯ReferenceError。
function bar(x = y, y = 2) { return[x,y] } bar() // 報錯
如上程式碼所示,呼叫bar函數會報錯,因為引數x的預設值等於另一個引數y,但是x在宣告的時候y還沒有宣告,屬於死區
。
總之,只要進入當前作用域,所要使用的變數就已經存在,但是不可獲取,只有等到宣告變數的那一行程式碼出現,才可以獲取和使用該變數。
其實let和const是存在變數提升的,但是由於暫時性死區的關係,變數已經存在了,但是不可獲取,要等到宣告變數的時候才可以獲取和使用。
let不允許在校內共同作用域內重複宣告同一個變數,這個就不用說了大家都知道。
let a = 1; let a = 2; // 報錯
我們都知道const宣告一個唯讀的常數。修改這個值就會報錯。但是實際上保證的不是變數的值不能改動,而是變數指向的那個記憶體地址不能改動。
對於簡單資料型別來說,值就是儲存在變數指向的記憶體地址中,因此等同於常數。
而對於複合型別的資料,變數指向的記憶體地址儲存的是一個指標,const只保證指標是固定,不保證內部的結構是不是可變的。
// 給物件新增一個屬性 const foo = {} foo.name = 123 console.log(foo.name) // 123 // 將foo指向另一個物件,就會報錯 foo = {} // 報錯。
如果想要將物件凍結,可以使用Object.freeze
const foo = Object.freeze({});
函數能不能在塊級作用域中宣告呢?
ES5中是規定函數只能在頂級作用域和函數作用域之中宣告,不能在塊級作用域宣告。
ES6中引入了塊級作用域,明確允許在塊級作用域之中宣告函數。而且。函數宣告的語句的行為類似於let,在塊級作用域之外不可參照。
function f() { console.log('I am outside!') } (function() { if(false) { function f() { console.log('I am inside') } } } f(); }())
上面的程式碼,在es5中執行時會得到I am inside!
,因為if內部的f函數會被提升到函數頭部。
但是在ES6環境則會報錯,為什麼呢?
因為遊覽器的實現有自己的方式:
所以上述程式碼實際在ES6的遊覽器中會生成這樣的程式碼:
function f() { console.log("I am outside!"); } (function () { var f = undefined; if (false) { function f() { console.log("I am inside"); } } })();
因此,應該避免在塊級作用域內宣告函數,如果確定需要寫成函數表示式的形式,而不是函數宣告語句。
到此這篇關於詳細解析let和const命令的文章就介紹到這了,更多相關let和const內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45