@thefourtheye ถูกต้องในการบอกว่าตัวแปรเหล่านี้ไม่สามารถเข้าถึงได้ก่อนที่จะมีการประกาศ อย่างไรก็ตามมันซับซ้อนกว่านั้นเล็กน้อย
มีการประกาศตัวแปรด้วยlet
หรือconst
ไม่ยก เกิดอะไรขึ้นที่นี่จริงเหรอ?
ประกาศทั้งหมด ( var
, let
, const
, function
, function*
, class
) เป็น "ยก"ใน JavaScript ซึ่งหมายความว่าหากมีการประกาศชื่อในขอบเขตในขอบเขตนั้นตัวระบุจะอ้างอิงตัวแปรนั้นเสมอ:
x = "global";
// function scope:
(function() {
x; // not "global"
var/let/… x;
}());
// block scope (not for `var`s):
{
x; // not "global"
let/const/… x;
}
นี่คือความจริงทั้งสำหรับการทำงานและป้องกันขอบเขต1
ความแตกต่างระหว่างvar
/ function
/ function*
ประกาศและlet
/ const
/ class
ประกาศเป็นinitialisation
อดีตจะเริ่มต้นด้วยundefined
หรือฟังก์ชั่น (เครื่องกำเนิดไฟฟ้า) ขวาเมื่อมีการสร้างการผูกที่ด้านบนของขอบเขต ตัวแปรที่ประกาศโดย lexically จะยังคงไม่ถูกกำหนดค่าเริ่มต้นไว้ ซึ่งหมายความว่ามีReferenceError
ข้อผิดพลาดเกิดขึ้นเมื่อคุณพยายามเข้าถึง มันจะได้รับการ initialised เมื่อlet
/ const
/ class
คำสั่งประเมินทุกอย่างก่อน (เหนือ) ที่เรียกว่าเขตตายชั่วคราว
x = y = "global";
(function() {
x; // undefined
y; // Reference error: y is not defined
var x = "local";
let y = "local";
}());
ขอให้สังเกตว่าlet y;
คำสั่งเริ่มต้นตัวแปรด้วยundefined
เช่นlet y = undefined;
จะมี
ชั่วคราวเขตตายไม่ได้เป็นที่ตั้งของประโยค แต่ใช้เวลาระหว่างตัวแปร (ขอบเขต) การสร้างและการ initialisation ไม่ใช่ข้อผิดพลาดในการอ้างอิงตัวแปรในโค้ดด้านบนการประกาศตราบใดที่รหัสนั้นไม่ได้ถูกดำเนินการ (เช่นฟังก์ชันของร่างกายหรือรหัสตายตัว) และมันจะส่งข้อยกเว้นถ้าคุณเข้าถึงตัวแปรก่อนการเริ่มต้นแม้ว่าการเข้าถึง โค้ดต่ำกว่าการประกาศ (เช่นในการประกาศฟังก์ชั่นแบบยกที่เรียกว่าเร็วเกินไป)
มีความแตกต่างระหว่างlet
และconst
ในเรื่องนี้หรือไม่?
ไม่พวกเขาทำงานเหมือนที่ได้รับการยกย่อง ข้อแตกต่างระหว่างพวกเขาก็คือconst
มดจะต้องเป็นและสามารถได้รับมอบหมายเฉพาะในส่วนเริ่มต้นของการประกาศ ( const one = 1;
ทั้งconst one;
มอบหมายและต่อมาเหมือนอย่างone = 2
ไม่ถูกต้อง)
1: var
การประกาศยังคงใช้งานได้เฉพาะในระดับฟังก์ชันเท่านั้น
let foo = () => bar; let bar = 'bar'; foo();
แสดงให้เห็นถึงการประกาศทั้งหมดมีผลบังคับใช้ดียิ่งขึ้นเพราะมันไม่ชัดเจนเนื่องจากโซนตายชั่วคราว