av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

知道臨時死區(qū)你才能更好的使用JS變量

首先,來個一個簡單的問題。下列哪段代碼會產(chǎn)生錯誤:

成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設、高性價比新平網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式新平網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設找我們,業(yè)務覆蓋新平地區(qū)。費用合理售后完善,10余年實體公司更值得信賴。

第一個創(chuàng)建實例,然后定義使用的類:

 
 
 
 
  1. new Car('red'); // 是否會報錯? 
  2.  
  3. class Car { 
  4.   constructor(color) { 
  5.     this.color = color; 
  6.   } 

或者先于函數(shù)定義之前調(diào)用函數(shù):

 
 
 
 
  1. greet('World'); // 是否會報錯? 
  2.  
  3. function greet(who) { 
  4.   return `Hello, ${who}!`; 
  5. }    

正確的答案是:第一個代碼片段會報 ReferenceError: Cannot access 'Car' before initialization 錯誤。第二個代碼正常運行。

如果你的答案與上述不同,或者你在不知道這背后的原理是什么而進行了猜測,那么你需要掌握臨時死區(qū)(TDZ)的知識。

TDZ 管理 let、const 和 class 語法的可用性。變量在 JS 中的工作方式非常重要。

1. 什么是臨時死區(qū)

咱們先從一個簡單的 const 變量聲明開始。首先聲明并初始化變量,然后訪問它,一切正常運行:

 
 
 
 
  1. const white = '#FFFFFF';  
  2. white; // => '#FFFFFF' 

那如果在 聲明之前訪問 white 變量,會怎么樣?

 
 
 
 
  1. white; // throws `ReferenceError`  
  2. const white = '#FFFFFF';  
  3. white; 

在 const white = '#FFFFFF' 語句之前的代碼行中,變量 white 位于臨時死區(qū)。

在 TDZ 中訪問 white 后,JS拋出ReferenceError: Cannot access 'white' before initialization

臨時死區(qū)語義禁止在變量聲明之前訪問它。它加強了順序:在聲明之前不要使用任何東西。

2. 受 TDZ 影響的聲明

來看看受 TDZ 影響的聲明。

(1) const變量

如前所述,const 變量位于聲明和初始化行之前的 TDZ 中:

 
 
 
 
  1. // 無法工作 
  2. pi; // throws `ReferenceError` 
  3.  
  4. const pi = 3.14; 

咱們必須在聲明之后使用 const 變量:

 
 
 
 
  1. const pi = 3.14; 
  2.  
  3. // Works! 
  4. pi; // => 3.14 

(2) let 變量

在聲明行之前,let 聲明語句也會受到 TDZ 的影響:

 
 
 
 
  1. // 無法工作 
  2. count; // throws `ReferenceError` 
  3.  
  4. let count; 
  5.  
  6. count = 10; 

同樣,僅在聲明之后使用 let 變量:

 
 
 
 
  1. let count; 
  2.  
  3. // Works! 
  4. count; // => undefined 
  5.  
  6. count = 10; 
  7.  
  8. // Works! 
  9. count; // => 10 

(3) class 的聲明

正如在介紹中看到的,在定義 class 之前不能使用它:

 
 
 
 
  1. // 無法工作 
  2. const myNissan = new Car('red'); // throws `ReferenceError` 
  3.  
  4. class Car { 
  5.   constructor(color) { 
  6.     this.color = color; 
  7.   } 

(4) 構(gòu)造函數(shù)內(nèi)部的 super()

如果在構(gòu)造函數(shù)中調(diào)用 super()之前擴展父類,則此綁定位于 TDZ 中。

 
 
 
 
  1. class MuscleCar extends Car { 
  2.   constructor(color, power) { 
  3.     this.power = power; 
  4.     super(color); 
  5.   } 
  6.  
  7. // Does not work! 
  8. const myCar = new MuscleCar('blue', '300HP'); // `ReferenceError` 

在構(gòu)造 constructor() 中,在調(diào)用super()之前不能使用 this。

TDZ 建議調(diào)用父構(gòu)造函數(shù)來初始化實例。這樣做之后,實例就準備好了,就可以在子構(gòu)造函數(shù)中進行調(diào)整。

 
 
 
 
  1. class MuscleCar extends Car { 
  2.   constructor(color, power) { 
  3.     super(color); 
  4.     this.power = power; 
  5.   } 
  6.  
  7. // Works! 
  8. const myCar = new MuscleCar('blue', '300HP'); 
  9. myCar.power; // => '300HP' 

(5) 默認函數(shù)參數(shù)

默認參數(shù)存在于一個中間作用域中,與全局作用域和函數(shù)作用域分離。默認參數(shù)也遵循 TDZ 限制。

 
 
 
 
  1. const a = 2; 
  2. function square(aa = a) { 
  3.   return a * a; 
  4. // Does not work! 
  5. square(); // throws `ReferenceError` 

在聲明表達式 a = a之前,在表達式的右側(cè)使用參數(shù) a,這將生成關于 a 的引用錯誤。

確保在聲明和初始化之后使用默認參數(shù)。咱們可以使用一個特殊的變量 init,該變量在使用前已初始化:

 
 
 
 
  1. const init = 2; 
  2. function square(a = init) { 
  3.   return a * a; 
  4. // Works! 
  5. square(); // => 4 

3. var, function, import 語句

與上述陳述相反,var 和 function 定義不受 TDZ 的影響。它們被提升到當前的作用域頂部。

如果在聲明之前訪問 var 變量,則只會得到一個 undefined的變量

 
 
 
 
  1. // 正常運行, 但不要這樣做! 
  2. value; // => undefined 
  3.  
  4. var value; 

但是,可以根據(jù)函數(shù)的定義位置來使用它:

 
 
 
 
  1. // 正常工作 
  2. greet('World'); // => 'Hello, World!' 
  3.  
  4. function greet(who) { 
  5.   return `Hello, ${who}!`; 
  6.  
  7. // 正常工作 
  8. greet('Earth'); // => 'Hello, Earth!' 

通常,咱們一般對函數(shù)的實現(xiàn)不太感興趣,而只是想調(diào)用它。因此,有時在定義函數(shù)之前先調(diào)用該函數(shù)是有意義的。

有趣的是,import 模塊也被提升了。

 
 
 
 
  1. // 正常工作 
  2. myFunction(); 
  3.  
  4. import { myFunction } from './myModule'; 

當然,建議將 import 寫在文件開頭,以便讀寫方法。

4. TDZ 中的 typeof 行為

typeof 操作符用于確定是否在當前作用域內(nèi)定義了變量。

例如,未定義變量 notDefined。對該變量應用 typeof 操作符不會引發(fā)錯誤:

 
 
 
 
  1. typeof notDefined; // => 'undefined' 

因為變量沒有定義,所以 typeof notDefined 的值為 undefined。

但是 typeof 操作符在與臨時死區(qū)中的變量一起使用時具有不同的行為。在本例中,JS 拋出一個錯誤:

 
 
 
 
  1. typeof variable; // throws `ReferenceError`  
  2. let variable; 

此引用錯誤背后的原因是您可以靜態(tài)地(僅通過查看代碼)確定已經(jīng)定義了該變量。

5. TDZ 在當前作用域內(nèi)采取行動

臨時死區(qū)在聲明語句所在的作用域內(nèi)影響變量。

來看看例子:

 
 
 
 
  1. function doSomething(someVal) { 
  2.   // 函數(shù)作用域 
  3.   typeof variable; // => undefined 
  4.   if (someVal) { 
  5.     // 內(nèi)部塊使用域 
  6.     typeof variable; // throws `ReferenceError` 
  7.     let variable; 
  8.   } 
  9. doSomething(true); 

有 2 個作用域:

  • 函數(shù)作用域
  • 定義 let 變量的內(nèi)部塊作用域

在函數(shù)作用域中,typeof variable 的計算結(jié)果為 undefined。在這里,let 變量語句的 TDZ 沒有作用。

在內(nèi)部作用域中,typeof variable 語句在聲明之前使用一個變量,拋出一個錯誤。ReferenceError:在初始化之前不能訪問‘variable’,TDZ 只存在于這個內(nèi)部作用域內(nèi)。

6. 總結(jié)

TDZ 是影響 const、let 和 class 語句可用性的重要概念。它不允許在聲明之前使用變量。

相反,可以在聲明之前使用 var 變量時,var 變量會繼承較舊的行為,應該避免這樣做。

在我看來,TDZ是語言規(guī)范中良好的編碼實踐之一。


分享名稱:知道臨時死區(qū)你才能更好的使用JS變量
本文網(wǎng)址:http://uogjgqi.cn/article/dhgdosi.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流