摘要:由于當時我本身也還不知道這一回事沒有看懂,所以就花了一些時間去搞清楚什么是及會帶來一些什么問題,本文主要是用于介紹我對的一些理解,如有問題,多謝指出。
原文鏈接:https://acrens.github.io/2017/01/22/2017-01-22-TDZ/
春節快到了,假期也快到了,空閑之余刷個微博,看見 @ruanyf 提出了一個問題與 TDZ 有關,但是貌似阮大當時還沒有意識到這個問題,多虧一些其他業內同仁提出了與 TDZ 相關;當然,以阮大的能力這都不是事。由于當時我本身也還不知道 TDZ 這一回事沒有看懂,所以就花了一些時間去搞清楚什么是 TDZ 及TDZ會帶來一些什么問題,本文主要是用于介紹我對 TDZ 的一些理解,如有問題,多謝指出。
案例一
代碼
let y = 1; function foo(x = y, y) { console.log(x); } foo(); // ReferenceError: y is not defined
解讀
當函數存在默認參數時,且調用方法不傳任何參數,會存在三個作用域環境;
全局作用域、參數作用域、函數體作用域;
當執行 foo 函數時,參數作用域在 x = y 之后才定義 let y,注意:let 定義,所以根據 let 定義變量的作用知道 x = y 肯定會報錯;
代碼翻譯:將以上代碼翻譯之后可以按下面代碼片段閱讀更易于理解
function analysis() { "use strict"; let y = 1; function foo() { let x = arguments[0] !== (void 0) ? arguments[0] : y; // y not defined let y = arguments[1]; } foo(); return {}; }
案例二
代碼
let y = 1; function foo(x = function(){console.log(y)}, y = 2) { x(); // 2 y = 3; x(); // 3 } foo(); console.log(y); //1
解讀
當函數存在默認參數時,且調用方法不傳任何參數,會存在三個作用域環境;
全局作用域、參數作用域、函數體作用域;
當執行 foo 函數時,x 被申明為匿名函數變量,此時函數并未被執行,所以正常;之后定義 y 值為 2,此時調用 x() 輸出的當然是變量 y 的值,之后繼續修改 y 的值,再繼續調用 x(),輸出 y 最新值 3;當執行外部 console.log(y) 時并不能訪問內部函數變量,訪問的變量是當前域下的 y = 1 的值 1,所以輸出 1;
代碼翻譯:將以上代碼翻譯之后可以按下面代碼片段閱讀更易于理解
function analysis() { "use strict"; let y = 1; function foo() { let x = arguments[0] !== (void 0) ? arguments[0] : function() { console.log(y); }; let y = arguments[1] !== (void 0) ? arguments[1] : 2; x(); // 2 y = 3; x(); // 3 } foo(); console.log(y); // 1 return {}; }
案例三
代碼
let y = 1; function foo(x = function(){console.log(y)}) { let y = 3; x(); // 1 } foo();
解讀
當函數存在默認參數時,且調用方法不傳任何參數,會存在三個作用域環境;
全局作用域、參數作用域、函數體作用域;
當執行 foo 函數時,x 被賦值為一個匿名函數的變量,且存在與參數作用域內,let y = 3 會被定義到函數體作用域內,屬于參數作用域的內部函數;當 x() 執行時是在函數體作用域定被調用,但是其定義是在參數作用域,所以執行環境是在參數作用域內,此時在參數作用域沒有定義 y 變量,也不能訪問內部函數 funBody 內部定義的變量 y,此時往上級函數查找是否存在 y 被定義,如果被定義則輸出其值,所以輸出最外層變量 y 的值 1;
代碼翻譯:將以上代碼翻譯之后可以按下面代碼片段閱讀更易于理解
function analysis() { "use strict"; let y = 1; function foo() { let x = arguments[0] !== (void 0) ? arguments[0] : function() { console.log(y); }; function funBody() { let y = 3; x(); } funBody(); } foo(); return {}; }
案例四
代碼
function foo(x = function(){console.log(y)}) { let y = 3; x(); // // ReferenceError: y is not defined } foo();
解讀
當函數存在默認參數時,且調用方法不傳任何參數,會存在三個作用域環境;
全局作用域、參數作用域、函數體作用域;
當執行 foo 函數時,x 被賦值為一個匿名函數的變量,且存在與參數作用域內,let y = 3 會被定義到函數體作用域內,屬于參數作用域的內部函數;當 x() 執行時是在函數體作用域定被調用,但是其定義是在參數作用域,所以執行環境是在參數作用域內,此時在參數作用域沒有定義 y 變量,也不能訪問內部函數 funBody 內部定義的變量 y,此時往上級函數查找是否存在 y 被定義,如果被定義則輸出其值,否則報 y 沒有被定義錯誤,此案例只是案例三的一種測試;
代碼翻譯:將以上代碼翻譯之后可以按下面代碼片段閱讀更易于理解
function analysis() { "use strict"; function foo() { let x = arguments[0] !== (void 0) ? arguments[0] : function() { console.log(y); }; function funBody() { let y = 3; x(); } funBody(); } foo(); return {}; }參考
以上核心部分在代碼翻譯部分,通過配合一下資料及個人的理解,翻譯出通俗易懂的代碼:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone_and_errors_with_let;
http://dmitrysoshnikov.com/ecmascript/es6-notes-default-values-of-parameters/#tdz-temporal-dead-zone-for-parameters;
https://github.com/google/traceur-compiler/issues/1604。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/81315.html
摘要:以英文名詞來說明,是時間的暫時的意義,則是死區,意指電波達不到的區域。所以可以翻為時間上暫時的無法達到的區域,簡稱為時間死區或暫時死區。以聲明的變量或常量,必需是經過對聲明的賦值語句的求值后,才算初始化完成,創建時并不算初始化。 Temporal Dead Zone(TDZ)是ES6(ES2015)中對作用域新的專用語義。TDZ名詞并沒有明確地寫在ES6的標準文件中,一開始是出現在ES...
摘要:會出現這樣的情況是因為擁有暫時性死區。規定暫時性死區和語句不出現變量提升,主要是為了減少運行時錯誤,防止在變量聲明前就使用這個變量,從而導致意料之外的行為。 首先我們應該知道js引擎在讀取js代碼時會進行兩個步驟: 第一個步驟是解釋。 第二個步驟是執行。 所謂解釋就是會先通篇掃描所有的Js代碼,然后把所有聲明提升到頂端,第二步是執行,執行就是操作一類的。 我們先來看個簡單的變量提升...
摘要:和都能夠聲明塊級作用域,用法和是類似的,的特點是不會變量提升,而是被鎖在當前塊中。聲明常量,一旦聲明,不可更改,而且常量必須初始化賦值。臨時死區臨時死區的意思是在當前作用域的塊內,在聲明變量前的區域叫做臨時死區。 主要知識點有:var變量提升、let聲明、const聲明、let和const的比較、塊級綁定的應用場景showImg(https://segmentfault.com/img...
摘要:眾所周知,中的聲明存在變量提升機制,因此引用了塊級作用域來強化對變量生命周期的控制聲明不會被提升,有幾個需要注意的點不能被重復聲明假設作用域中已經存在某個標識符無論該標識符是通過聲明還是變量聲明,此時再使用或關鍵定聲明會拋錯此處則會拋出錯誤 眾所周知,js中的var聲明存在變量提升機制,因此ESMAScript 6引用了塊級作用域來強化對變量生命周期的控制let const 聲明不會被...
閱讀 854·2021-11-24 10:44
閱讀 2790·2021-11-11 16:54
閱讀 3192·2021-10-08 10:21
閱讀 2096·2021-08-25 09:39
閱讀 2914·2019-08-30 15:56
閱讀 3466·2019-08-30 13:46
閱讀 3502·2019-08-23 18:09
閱讀 2089·2019-08-23 17:05