我發現了我以前從未想過的非常奇怪的行為。我不確定這是否與 TDZ 相關,因為我認為 TDZ 是從外部作用域到內部作用域,而不是像這種情況那樣反過來。請注意arg以下示例。
// Works
const test = {
func: (arg) => {
const obj = {
foo: arg,
}
return obj.foo;
}
}
// Error
const test = arg => {
{
const arg = arg; // Cannot access 'arg' before initialization
}
}
uj5u.com熱心網友回復:
問題是您在功能塊內宣告了一個新 arg變數,并將該變數隱藏arg在外部作用域中,例如宣告為函式引數的變數。
因此,賦值arg右側const arg = arg;的 參考與左側參考的變數相同的變數。它沒有參考箭頭函式arg引數。因此,您完全按照錯誤說明進行操作,在初始化變數之前參考它(同時嘗試初始化它!)。
這可以通過使用唯一名稱輕松演示:
const test = arg => {
{
const inner_arg = arg;
}
}
你為什么要使用相同的名字?不僅會導致上述問題,還無法讀取代碼。也許您是出于習慣這樣做,就像在類建構式中那樣?但在這種情況下,您可以使用 區分引數和類欄位this,例如this.arg = arg。
uj5u.com熱心網友回復:
錯誤訊息的原因是letandconst宣告都是塊范圍的,這意味著它們只能在{ }它們周圍的范圍內訪問。所以由于const或let與variable (arg)從外范圍將不被如果另一個訪問variable (arg)的塊范圍內被定義。
或者換句話說:arga parenthesesor內部的變數curly brackets與arg您傳遞給函式的變數不同,因為您使用了letorconst內部。
在決議塊作用域時,引擎已經為內部定義的每個變數保留了名稱。但是只有在使用 const 或 let 宣告和評估之后才能訪問它們。
因此,在寫入時讀取它會導致您看到的錯誤。
var variable;
{ // [block/env start]
let variable = variable; // ReferenceError: Cannot access 'variable' before initialization
} // [block/env end]
在此期間發生的事情let variable = variable是它必須在將值/參考分配給左側之前讀取右側,但是根據定義,變數在宣告之前不可用,因此它會引發錯誤。
另一個例子是:
var variable;
{
console.log(variable); // ReferenceError: Cannot access 'variable' before initialization
let variable;
}
執行順序與您的示例中的分配類似,并引發相同的錯誤。它不會訪問外部,variable因為variable使用 let/const 在該塊范圍內定義了另一個。
您還可以查看Let 和 Const 宣告。
let 和 const 宣告定義了作用域為運行執行背景關系的 LexicalEnvironment 的變數。變數在其包含的環境記錄被實體化時創建,但在評估變數的 LexicalBinding 之前不能以任何方式訪問。當 LexicalBinding 被求值時,一個由帶有 Initializer 的 LexicalBinding 定義的變數被分配了它的 Initializer 的 AssignmentExpression 的值,而不是在創建變數時。如果 let 宣告中的 LexicalBinding 沒有初始值設定項,則在評估 LexicalBinding 時會為變數分配未定義的值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/375461.html
標籤:javascript 变量 范围 争论 常数
