ReferenceError in Temporal Dead Zone
๐Ÿ“„

ReferenceError in Temporal Dead Zone

Created
Jul 30, 2021 05:01 AM
Tags
js
JavaScript ๊ณต๋ถ€ํ•˜๋Š” ์นœ๊ตฌ๊ฐ€ ๋ฌผ์–ด๋ด์„œ ์•Œ๋ ค์ค„ ๊ฒธ ์ •๋ฆฌ
ย 
(1)
์•„๋ž˜์˜ ๋‘ ์ฝ”๋“œ๋Š” ๋ธŒ๋ผ์šฐ์ €(Chrome 91)์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ–๋Š”๋‹ค
ย 
console.log(foo); // ReferenceError: foo is not defined
let foo;
{
  console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
  let foo;
}
ย 
์ด ๋‘˜์ด ์–ด๋–ค ์ฐจ์ด๋ฅผ ๊ฐ–๊ณ  ์žˆ๊ธฐ์— ์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒƒ์ผ๊นŒ?
์ด๋ฅผ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž
ย 
ย 
(2)
์ผ๋‹จ, Hoisting์ด Spec์—๋Š” ์–ด๋–ป๊ฒŒ ๋ช…์‹œ๋˜์–ด์žˆ๋Š”์ง€ ๋ณด๋„๋ก ํ•˜๋ฉด...
ย 
var ๊ฐ™์€ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™๋‹ค[1]
ย 
Var variables are created when their containing Environment Record is instantiated and are initialized to undefined when created. A variable defined by a VariableDeclaration with an Initializer is assigned the value of its Initializer's AssignmentExpression when the VariableDeclaration is executed, not when the variable is created.
ย 
var ํ‚ค์›Œ๋“œ๋กœ ์ •์˜๋˜๋Š” ๋ณ€์ˆ˜๋Š” ์ž์‹ ์ด ์†ํ•œ Environment Record[3]๊ฐ€ ์ดˆ๊ธฐํ™” ๋  ๋•Œ undefined ๊ฐ’์„ ๊ฐ–๊ณ  ์ƒ์„ฑ๋˜๋ฉฐ, ์ดํ›„ ์‹ค์ œ๋กœ ๊ฐ’์ด ํ• ๋‹น๋˜๋Š” ๊ตฌ๋ฌธ(AssignmentExpression[4])์„ ๋งˆ์ฃผํ•  ๋•Œ ๊ฐ’์ด ๋ณ€์ˆ˜์— ํ• ๋‹น๋œ๋‹ค๋Š” ๋ง
ย 
์ด์™€๋Š” ๋‹ค๋ฅด๊ฒŒ let ๊ณผ const ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค[2]
ย 
The variables are created when their containing Environment Record is instantiated but may not be accessed in any way until the variable's LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer's AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created.
ย 
let ๊ทธ๋ฆฌ๊ณ  const ํ‚ค์›Œ๋“œ๋กœ ์ •์˜๋˜๋Š” ๋ณ€์ˆ˜ ์—ญ์‹œ ์ž์‹ ์ด ์†ํ•œ Environment Record๊ฐ€ ์ดˆ๊ธฐํ™” ๋  ๋•Œ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์€ ๋™์ผ
ย 
๋‹ค๋งŒ ์‹ค์ œ๋กœ ๋ฐ”์ธ๋”ฉ ๋˜๊ธฐ ์ „ ๊นŒ์ง€๋Š” ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ๋“  ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉฐ(TDZ, Temporal Dead Zone), ๋ฐ”์ธ๋”ฉ ์ดํ›„์—๋Š” ์ดˆ๊ธฐํ™” ๊ตฌ๋ฌธ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ’์ด ๋ณ€์ˆ˜์— ํ• ๋‹น๋œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค
ย 
ย 
(3)
๊ทธ๋Ÿผ ๊ฐ๊ฐ์˜ Scope๋Š” ์–ด๋–ป๊ฒŒ ์ •์˜๋ ๊นŒ?
์ด๊ฑด Spec๊ณผ Ecma TC39 ๋ฉค๋ฒ„์˜ ๋‹ต๋ณ€์„ ํ†ตํ•ด ์•Œ์•„๋ณด์ž๋ฉด...
ย 
๋จผ์ € var ์˜ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค[1]
ย 
A var statement declares variables that are scoped to the running execution context's VariableEnvironment.
ย 
Running Execution Context์˜ VariableEnvironment๋กœ Scope๊ฐ€ ์žกํžŒ๋‹ค๋Š” ๋ง
ย 
let ๊ทธ๋ฆฌ๊ณ  const ๋Š” ์ด๋ ‡๋‹ค[2]
ย 
let and const declarations define variables that are scoped to the running execution context's LexicalEnvironment.
ย 
Running Execution Context์˜ LexicalEnvironment๋กœ Scope๊ฐ€ ์žกํžŒ๋‹ค๊ณ  ํ•œ๋‹ค
ย 
ย 
(4)
VariableEnvironment์™€ LexicalEnvironment๋Š” ์–ด๋–ค ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ผ๊นŒ? ๊ทธ๋ฆฌ๊ณ  ์–ธ์ œ ์ƒ์„ฑ(์ดˆ๊ธฐํ™”)์ด ๋˜๋Š” ๊ฒƒ์ผ๊นŒ?
ย 
์ฐจ์ด๋ถ€ํ„ฐ ๋ณด์ž๋ฉด ์ด๋ ‡๋‹ค[5]
ย 
A LexicalEnvironment is a local lexical scope, e.g., for let-defined variables. If you define a variable with let in a catch block, it is only visible within the catch block, and to implement that in the spec, we use a LexicalEnvironment. VariableEnvironment is the scope for things like var-defined variables. vars can be thought of as "hoisting" to the top of the function.
ย 
๋‹น์—ฐํ•œ ๋ง์ด๊ธด ํ•œ๋ฐ... ์ •๋ฆฌํ•˜๋ฉด ์ด๋ ‡๋‹ค
ย 
  • LexicalEnvironment(Local lexical Scope) : let ๊ณผ ๊ฐ™์€ ๋ณ€์ˆ˜๊ฐ€ ์„ ์–ธ๋  ๋•Œ์˜ Scope
  • VariableEnvironment : var ๊ณผ ๊ฐ™์€ ๋ณ€์ˆ˜๊ฐ€ ์„ ์–ธ๋  ๋•Œ์˜ Scope
ย 
์ƒ์„ฑ๋˜๋Š” ์‹œ์ ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค
ย 
To implement this in the spec, we give functions a new VariableEnvironment, but say that blocks inherit the enclosing VariableEnvironment.
ย 
VariableEnvironment๋Š” ํ•จ์ˆ˜์™€ ํ•จ๊ป˜[5]
ย 
{ StatementList } 1. Let oldEnv be the running execution context's LexicalEnvironment. 2. Let blockEnv be NewDeclarativeEnvironment(oldEnv). 3. Perform BlockDeclarationInstantiation(StatementList, blockEnv). 4. Set the running execution context's LexicalEnvironment to blockEnv. 5. Let blockValue be the result of evaluating StatementList. 6. Set the running execution context's LexicalEnvironment to oldEnv. 7. Return blockValue.
ย 
LexicalEnvironment๋Š” Block ๊ตฌ๋ฌธ๊ณผ ํ•จ๊ป˜[6] ์ƒ์„ฑ์ด ๋œ๋‹ค๋Š” ๊ฒƒ
ย 
ย 
(5)
์ž, ๊ทธ๋Ÿผ ์ด์ œ ์ฒซ ๋ฒˆ์งธ ๊ฒฝ์šฐ์˜€๋˜ ReferenceError: foo is not defined ๋ฅผ ์„ค๋ช…ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค
ย 
console.log(foo); // ReferenceError: foo is not defined
let foo;
ย 
์œ„์—์„œ ์„ค๋ช…ํ–ˆ๋‹ค์‹ถ์ด, let ์€ Environment Record๊ฐ€ ์ธ์Šคํ„ด์Šคํ™” ๋  ๋•Œ ๊ฐ™์ด ์‹คํ–‰๋œ๋‹ค๊ณ  ํ–ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์™œ defined๊ฐ€ ๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์ผ๊นŒ?
ย 
์‚ฌ์‹ค, ์•Œ๋‹ค์‹ถ์ด JavaScript๋Š” ์œ„์—์„œ๋ถ€ํ„ฐ ํ•œ ์ค„ ์”ฉ ํŒŒ์‹ฑ ๋ฐ ์‹คํ–‰ํ•ด ๋‚˜๊ฐ€๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์–ธ์–ด์ด๋‹ค
ย 
๋”ฐ๋ผ์„œ ์ฝ”๋“œ๋Š” ์ด๋ ‡๊ฒŒ ๋‚˜๋ˆ ์„œ ์‹คํ–‰๋œ๋‹ค
ย 
console.log(foo);
let foo;
ย 
์ฒซ ๋ฒˆ์งธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด? ๋‹น์—ฐํžˆ foo ๋ผ๋Š” ๋ณ€์ˆ˜๊ฐ€ ์•„์˜ˆ ์ƒ์„ฑ์กฐ์ฐจ ๋˜์–ด์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ReferenceError: foo is not defined ๋ผ๋Š” ์—๋Ÿฌ๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒƒ
ย 
์ง€๊ธˆ ๋‹น์žฅ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ Console์„ ์ด์šฉํ•ด console.log(notDefinedVariable) ๋งŒ์„ ์ž…๋ ฅํ•ด๋ณด๋ฉด ๋™์ผํ•œ ์—๋Ÿฌ๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค
ย 
ย 
(6)
์ด์ œ ๋‘ ๋ฒˆ์งธ ๊ฒฝ์šฐ
ย 
{
  console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
  let foo;
}
ย 
์—ฌ๊ธฐ์„œ๋Š” Block Statement๊ฐ€ ๋‚˜์˜จ๋‹ค
ย 
JavaScript์—์„œ๋Š” Block Statement๋ฅผ ๋งˆ์ฃผํ•  ๊ฒฝ์šฐ ์ด ์•ˆ์— ๋“ค์–ด์žˆ๋Š” Variables, Constants, Functions, Classes์— ๋Œ€ํ•ด Environment Record๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•œ๋‹ค[7]
ย 
์ด ๊ณผ์ •์—์„œ, ์•ž์„œ ๋งํ–ˆ๋“ฏ์ด foo ๋ผ๋Š” ๋ณ€์ˆ˜๊ฐ€ Environment Record์™€ ํ•จ๊ป˜ ์ƒ์„ฑ๋˜๊ฒŒ ๋˜๋Š” ๊ฒƒ
ย 
๋ฌผ๋ก  '์ ‘๊ทผ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ์—' ์œ„์™€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ๋˜๋Š” ๊ฒƒ์ด๋‹ค
ย 
์ด๊ฒƒ์ด ์ด ๋‘˜์˜ ์ฐจ์ด
ย 
ย 
(0)
References
ย 
ย 

Loading Comments...