溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

let和const命令的使用方法

發(fā)布時(shí)間:2021-06-23 15:05:42 來源:億速云 閱讀:153 作者:chen 欄目:編程語言

這篇文章主要講解了“l(fā)et和const命令的使用方法”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“l(fā)et和const命令的使用方法”吧!

var a = [];for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); /

上面代碼中,變量i是let聲明的,當(dāng)前的i只在本輪循環(huán)有效,所以每一次循環(huán)的i其實(shí)都是一個(gè)新的變量,所以最后輸出的是6。

一 不存在變量提升

let不像var那樣會(huì)發(fā)生“變量提升”現(xiàn)象。所以,變量一定要在聲明后使用,否則報(bào)錯(cuò)

二 暫時(shí)性死區(qū)

ES6明確規(guī)定,如果區(qū)塊中存在let和const命令,這個(gè)區(qū)塊對(duì)這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會(huì)報(bào)錯(cuò)。這在語法上,稱為“暫時(shí)性死區(qū)”(temporal dead zone,簡(jiǎn)稱TDZ)。

if (true) {  // TDZ開始
  tmp = 'abc'; // ReferenceError
  console.log(tmp); // ReferenceError
  let tmp; // TDZ結(jié)束
  console.log(tmp); // undefined
  tmp = 123;
  console.log(tmp); // 123}

“暫時(shí)性死區(qū)”也意味著typeof不再是一個(gè)百分之百安全的操作。

typeof x; // ReferenceErrorlet x;

有些“死區(qū)”比較隱蔽,不太容易發(fā)現(xiàn)。

function bar(x = y, y = 2) {  return [x, y];
}

bar(); // 報(bào)錯(cuò)

上面代碼中,調(diào)用bar函數(shù)之所以報(bào)錯(cuò)(某些實(shí)現(xiàn)可能不報(bào)錯(cuò)),是因?yàn)閰?shù)x默認(rèn)值等于另一個(gè)參數(shù)y,而此時(shí)y還沒有聲明,屬于”死區(qū)“。如果y的默認(rèn)值是x,就不會(huì)報(bào)錯(cuò),因?yàn)榇藭r(shí)x已經(jīng)聲明了。

ES6規(guī)定暫時(shí)性死區(qū)和let、const語句不出現(xiàn)變量提升,主要是為了減少運(yùn)行時(shí)錯(cuò)誤,防止在變量聲明前就使用這個(gè)變量,從而導(dǎo)致意料之外的行為。這樣的錯(cuò)誤在ES5是很常見的,現(xiàn)在有了這種規(guī)定,避免此類錯(cuò)誤就很容易了。

總之,暫時(shí)性死區(qū)的本質(zhì)就是,只要一進(jìn)入當(dāng)前作用域,所要使用的變量就已經(jīng)存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量。

三 不允許重復(fù)聲明

// 報(bào)錯(cuò)function () {
  let a = 10;  var a = 1;
}// 報(bào)錯(cuò)function () {
  let a = 10;
  let a = 1;
}function func(arg) {
  let arg; // 報(bào)錯(cuò)}function func(arg) {
  {
    let arg; // 不報(bào)錯(cuò)  }
}

四 塊級(jí)作用域

ES5只有全局作用域和函數(shù)作用域,沒有塊級(jí)作用域,這帶來很多不合理的場(chǎng)景。

第一種場(chǎng)景,內(nèi)層變量可能會(huì)覆蓋外層變量。

var tmp = new Date();function f() {
  console.log(tmp);  if (false) {    var tmp = "hello world";
  }
}

f(); // undefined

上面代碼中,函數(shù)f執(zhí)行后,輸出結(jié)果為undefined,原因在于變量提升,導(dǎo)致內(nèi)層的tmp變量覆蓋了外層的tmp變量。

第二種場(chǎng)景,用來計(jì)數(shù)的循環(huán)變量泄露為全局變量。三門峽婦科醫(yī)院http://www.smxrlyy.com/

var s = 'hello';for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}

console.log(i); // 5

上面代碼中,變量i只用來控制循環(huán),但是循環(huán)結(jié)束后,它并沒有消失,泄露成了全局變量。

塊級(jí)作用域的出現(xiàn),實(shí)際上使得獲得廣泛應(yīng)用的立即執(zhí)行匿名函數(shù)(IIFE)不再必要了。 

// IIFE寫法(function () {  var tmp = ...;
  ...
}());// 塊級(jí)作用域?qū)懛▄
  let tmp = ...;
  ...
}

const命令

const聲明一個(gè)只讀的常量。一旦聲明,常量的值就不能改變。

const聲明的變量不得改變值,這意味著,const一旦聲明變量,就必須立即初始化,不能留到以后賦值。

const foo;// SyntaxError: Missing initializer in const declaration

const的作用域與let命令相同:只在聲明所在的塊級(jí)作用域內(nèi)有效。

const命令聲明的常量也是不提升,同樣存在暫時(shí)性死區(qū),只能在聲明的位置后面使用。

const聲明的常量,也與let一樣不可重復(fù)聲明。

const a = [];
a.push('Hello'); // 可執(zhí)行a.length = 0;    // 可執(zhí)行a = ['Dave'];    // 報(bào)錯(cuò)

上面代碼中,常量a是一個(gè)數(shù)組,這個(gè)數(shù)組本身是可寫的,但是如果將另一個(gè)數(shù)組賦值給a,就會(huì)報(bào)錯(cuò)。

如果真的想將對(duì)象凍結(jié),應(yīng)該使用Object.freeze方法。

const foo = Object.freeze({});// 常規(guī)模式時(shí),下面一行不起作用;// 嚴(yán)格模式時(shí),該行會(huì)報(bào)錯(cuò)foo.prop = 123;

上面代碼中,常量foo指向一個(gè)凍結(jié)的對(duì)象,所以添加新屬性不起作用,嚴(yán)格模式時(shí)還會(huì)報(bào)錯(cuò)。

除了將對(duì)象本身凍結(jié),對(duì)象的屬性也應(yīng)該凍結(jié)。下面是一個(gè)將對(duì)象徹底凍結(jié)的函數(shù)。

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, value) => {    if ( typeof obj[key] === 'object' ) {
      constantize( obj[key] );
    }
  });
};

全局對(duì)象的屬性

未聲明的全局變量,自動(dòng)成為全局對(duì)象window的屬性,這被認(rèn)為是JavaScript語言最大的設(shè)計(jì)敗筆之一。這樣的設(shè)計(jì)帶來了兩個(gè)很大的問題,首先是沒法在編譯時(shí)就報(bào)出變量未聲明的錯(cuò)誤,只有運(yùn)行時(shí)才能知道,其次程序員很容易不知不覺地就創(chuàng)建了全局變量(比如打字出錯(cuò))。另一方面,從語義上講,語言的頂層對(duì)象是一個(gè)有實(shí)體含義的對(duì)象,也是不合適的。

 ES6為了改變這一點(diǎn),一方面規(guī)定,為了保持兼容性,var命令和function命令聲明的全局變量,依舊是全局對(duì)象的屬性;另一方面規(guī)定,let命令、const命令、class命令聲明的全局變量,不屬于全局對(duì)象的屬性。也就是說,從ES6開始,全局變量將逐步與全局對(duì)象的屬性脫鉤。

var a = 1;// 如果在Node的REPL環(huán)境,可以寫成global.a// 或者采用通用方法,寫成this.awindow.a // 1let b = 1;
window.b // undefined

上面代碼中,全局變量a由var命令聲明,所以它是全局對(duì)象的屬性;全局變量b由let命令聲明,所以它不是全局對(duì)象的屬性,返回undefined。

感謝各位的閱讀,以上就是“l(fā)et和const命令的使用方法”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)let和const命令的使用方法這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI