您好,登錄后才能下訂單哦!
這篇文章主要講解了“let和const命令的使用方法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“let和const命令的使用方法”吧!
var a = [];for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); /
上面代碼中,變量i是let聲明的,當前的i只在本輪循環有效,所以每一次循環的i其實都是一個新的變量,所以最后輸出的是6。
let不像var那樣會發生“變量提升”現象。所以,變量一定要在聲明后使用,否則報錯
ES6明確規定,如果區塊中存在let和const命令,這個區塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會報錯。這在語法上,稱為“暫時性死區”(temporal dead zone,簡稱TDZ)。
if (true) { // TDZ開始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ結束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123}
“暫時性死區”也意味著typeof不再是一個百分之百安全的操作。
typeof x; // ReferenceErrorlet x;
有些“死區”比較隱蔽,不太容易發現。
function bar(x = y, y = 2) { return [x, y]; } bar(); // 報錯
上面代碼中,調用bar函數之所以報錯(某些實現可能不報錯),是因為參數x默認值等于另一個參數y,而此時y還沒有聲明,屬于”死區“。如果y的默認值是x,就不會報錯,因為此時x已經聲明了。
ES6規定暫時性死區和let、const語句不出現變量提升,主要是為了減少運行時錯誤,防止在變量聲明前就使用這個變量,從而導致意料之外的行為。這樣的錯誤在ES5是很常見的,現在有了這種規定,避免此類錯誤就很容易了。
總之,暫時性死區的本質就是,只要一進入當前作用域,所要使用的變量就已經存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現,才可以獲取和使用該變量。
// 報錯function () { let a = 10; var a = 1; }// 報錯function () { let a = 10; let a = 1; }function func(arg) { let arg; // 報錯}function func(arg) { { let arg; // 不報錯 } }
ES5只有全局作用域和函數作用域,沒有塊級作用域,這帶來很多不合理的場景。
第一種場景,內層變量可能會覆蓋外層變量。
var tmp = new Date();function f() { console.log(tmp); if (false) { var tmp = "hello world"; } } f(); // undefined
上面代碼中,函數f執行后,輸出結果為undefined,原因在于變量提升,導致內層的tmp變量覆蓋了外層的tmp變量。
第二種場景,用來計數的循環變量泄露為全局變量。三門峽婦科醫院http://www.smxrlyy.com/
var s = 'hello';for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
上面代碼中,變量i只用來控制循環,但是循環結束后,它并沒有消失,泄露成了全局變量。
塊級作用域的出現,實際上使得獲得廣泛應用的立即執行匿名函數(IIFE)不再必要了。
// IIFE寫法(function () { var tmp = ...; ... }());// 塊級作用域寫法{ let tmp = ...; ... }
const聲明一個只讀的常量。一旦聲明,常量的值就不能改變。
const聲明的變量不得改變值,這意味著,const一旦聲明變量,就必須立即初始化,不能留到以后賦值。
const foo;// SyntaxError: Missing initializer in const declaration
const的作用域與let命令相同:只在聲明所在的塊級作用域內有效。
const命令聲明的常量也是不提升,同樣存在暫時性死區,只能在聲明的位置后面使用。
const聲明的常量,也與let一樣不可重復聲明。
const a = []; a.push('Hello'); // 可執行a.length = 0; // 可執行a = ['Dave']; // 報錯
上面代碼中,常量a是一個數組,這個數組本身是可寫的,但是如果將另一個數組賦值給a,就會報錯。
如果真的想將對象凍結,應該使用Object.freeze方法。
const foo = Object.freeze({});// 常規模式時,下面一行不起作用;// 嚴格模式時,該行會報錯foo.prop = 123;
上面代碼中,常量foo指向一個凍結的對象,所以添加新屬性不起作用,嚴格模式時還會報錯。
除了將對象本身凍結,對象的屬性也應該凍結。下面是一個將對象徹底凍結的函數。
var constantize = (obj) => { Object.freeze(obj); Object.keys(obj).forEach( (key, value) => { if ( typeof obj[key] === 'object' ) { constantize( obj[key] ); } }); };
未聲明的全局變量,自動成為全局對象window的屬性,這被認為是JavaScript語言最大的設計敗筆之一。這樣的設計帶來了兩個很大的問題,首先是沒法在編譯時就報出變量未聲明的錯誤,只有運行時才能知道,其次程序員很容易不知不覺地就創建了全局變量(比如打字出錯)。另一方面,從語義上講,語言的頂層對象是一個有實體含義的對象,也是不合適的。
ES6為了改變這一點,一方面規定,為了保持兼容性,var命令和function命令聲明的全局變量,依舊是全局對象的屬性;另一方面規定,let命令、const命令、class命令聲明的全局變量,不屬于全局對象的屬性。也就是說,從ES6開始,全局變量將逐步與全局對象的屬性脫鉤。
var a = 1;// 如果在Node的REPL環境,可以寫成global.a// 或者采用通用方法,寫成this.awindow.a // 1let b = 1; window.b // undefined
上面代碼中,全局變量a由var命令聲明,所以它是全局對象的屬性;全局變量b由let命令聲明,所以它不是全局對象的屬性,返回undefined。
感謝各位的閱讀,以上就是“let和const命令的使用方法”的內容了,經過本文的學習后,相信大家對let和const命令的使用方法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。