摘要:我們將循環執行五次,每次將一個函數到數組中。只有當你理解了,才能給出正確的答案。讀者提到的兩個問題聲明的變量不是完全不可更改。不僅如此,而且有些最新的瀏覽器也還沒有支持。
譯者按: 使用let的確會比var安全很多。
原文: Why You Shouldn’t Use ‘var’ Anymore
譯者: Fundebug
為了保證可讀性,本文采用意譯而非直譯。
我已經使用ES2015(ES6)的語法編寫JavaScript程序很久了,并且喜歡上它提供的新特性帶來的優雅和簡潔。我最習慣的就是不再使用var,而是let/const。我想當然的以為let僅僅是var的替代者,而事實上let還為我們提供了更加精細的作用域。
我大多數時候使用的變量都是用const來聲明,因為如果嘗試對使用const聲明的變量進行修改,將會報錯。這可以避免不小心將一個不該修改的常量值修改。但是,我們還是需要可以聲明可以被修改的變量,比如在循環里面的計數器,我們需要不斷地對改變了加1??墒菫槭裁次覀兪褂?b>let而不是var呢?
最簡單的答案就是let提供塊作用域(block-scoping),這會比var提供的以函數為作用域有更加精細化的控制。為了便于理解,我來用一個經典的前端工程師面試的問題來描述兩者的區別。
問題: 在下面的例子中,請說出控制臺的打印結果。
var callbacks = []; (function() { for (var i = 0; i < 5; i++) { callbacks.push( function() { return i; } ); } })(); console.log(callbacks.map( function(cb) { return cb(); } ));
我們將for循環執行五次,每次將一個函數push到callbacks數組中。最后callbacks數組里面的每一個函數的執行結果打印出來。
一個新手工程師經過深思熟慮可能會回答[0, 1 , 2, 3, 4], 然而卻掉入了JavaScript的"hoisting陷阱"。
只有當你理解了hoisting, 才能給出正確的答案[5, 5, 5, 5, 5]。
var callbacks = []; (function() { var i; for (i = 0; i < 5; i++) { callbacks.push( function() { return i; } ); } })(); console.log(callbacks.map( function(cb) { return cb(); } ));
注意上面的代碼,JavaScript將變量提升到函數定義的頂部,經過整個for循環,callbacks里面存儲的5個函數指向的同一個變量i的值已經是5。所以最終打印出來的值都為5。
在以前要通過各種奇淫技巧來解決這個問題,并成功返回[0, 1, 2, 3, 4], 現在我們有了let,就可以很簡單解決問題:
var callbacks = []; (function() { for (let i = 0; i < 5; i++) { callbacks.push( function() { return i; } ); } })(); console.log(callbacks.map( function(cb) { return cb(); } ));
因為let擁有塊作用域,所以使用let聲明的變量i不會被提升到函數頂部,i的作用域在for循環, 就會每次循環有獨立的值。
那我們是不是應該不要使用var了呢?如果你想要一個變量擁有函數作用域,var還是很有用的。
讀者提到的兩個問題:
const聲明的變量不是完全不可更改。比如:
const myNotQuiteImmutableObject = { thisCanBeChanged: "not immutable" }; myNotQuiteImmutableObject.thisCanBeChanged = "see I changed it.";
但是,使用const聲明可以阻止一些基本的更改,比如:
const immutableString = "you can"t change me"; immutableString = "D"OH!"; // error
如果你想要完全的不可更改,可以使用Facebook提供的Immutable庫。
老版本的瀏覽器不支持let。不僅如此,而且有些最新的瀏覽器也還沒有支持let。我們可以使用Babel來避免這個問題,Babel允許你使用所有最新的JavaScript功能,然后將其翻譯到甚至IE8都能支持的代碼。
歡迎加入我們Fundebug的JavaScript技術交流群: 622902485。
版權聲明:
轉載時請注明作者Fundebug以及本文地址:
https://blog.fundebug.com/201...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82923.html
摘要:用原生寫一個多動癥的簡歷預覽地址源碼地址最近在知乎上看到方應杭用寫了一個會動的簡歷,覺得挺好玩的,研究一下其實現思路,決定試試用原生來實現。 用原生js寫一個多動癥的簡歷 預覽地址源碼地址 最近在知乎上看到@方應杭用vue寫了一個會動的簡歷,覺得挺好玩的,研究一下其實現思路,決定試試用原生js來實現。 showImg(https://segmentfault.com/img/remot...
之前也有和大家講過有關JS的對象創建和對象繼承,本篇文章主要為大家做個匯總和梳理?! S中其實就是原型鏈繼承和構造函數繼承的毛病,還有就是工廠、構造、原型設計模式與JS繼承。 JS高級程序設計4:class繼承的重點,不只是簡簡單單的語法而已。 對象創建 不難發現,每一篇都離不開工廠、構造、原型這3種設計模式中的至少其一! 那JS為什么非要用到這種3種設計模式了呢?? 我們先從對...
let和const let和const兩者并不存在變量提升 這里要說明的是變量一定要在聲明后使用,否則報錯。 vara=[]; for(vari=0;i<10;i++){ a[i]=function(){ console.log(i); }; } a[6]();//10 變量i是var聲明的,我們要知道這里在全局范圍內都有效。我們要知道在每一次循環中,新的...
在過往學習的JavaScript都是在基礎,現在為大家介紹更為深入的JavaScript知識。 JavaScript函數 JavaScript函數和Java函數是有一部分相似的,所以學習起來也會相對簡單 基本構造 1.直接構造 //function代表函數標志,name為函數名稱,參數可有可無 functionname(參數){ //... return; } 2....
閱讀 2091·2023-04-26 02:41
閱讀 2151·2021-09-24 09:47
閱讀 1551·2019-08-30 15:53
閱讀 1209·2019-08-30 13:01
閱讀 1891·2019-08-29 11:27
閱讀 2866·2019-08-28 17:55
閱讀 1755·2019-08-26 14:00
閱讀 3388·2019-08-26 10:18