μλ°μ€ν¬λ¦½νΈλ₯Ό λ€λ£¨λ λ° μμ΄μ 'μ€μ½ν'λ λ§€μ° μ€μν κ°λ μ λλ€. μ€μ½νλ₯Ό μ΄ν΄νλ©΄ μ½λμ κ°λ μ±μ λμ΄κ³ , λ²κ·Έλ₯Ό μ€μ΄λ λ° ν° λμμ΄ λ©λλ€. μ΄λ² κΈμμλ μλ°μ€ν¬λ¦½νΈ μ€μ½νμ λν΄ κΈ°μ΄λΆν° κ³ κΈκΉμ§ 체κ³μ μΌλ‘ μμλ³΄κ² μ΅λλ€.
β£ λͺ©μ°¨
01. μλ°μ€ν¬λ¦½νΈ μ€μ½νλβ
μλ°μ€ν¬λ¦½νΈμμ μ€μ½ν(scope)λ λ³μλ ν¨μκ° μ κ·Όν μ μλ μ ν¨ λ²μλ₯Ό μλ―Έν©λλ€. μ΄λ μ½λμ μ€ν 컨ν μ€νΈμ λ°μ ν κ΄λ ¨μ΄ μμΌλ©°, μ€μ½νλ₯Ό μ μ΄ν΄ν΄μΌ μ½λμ νλ¦μ μ νν νμ ν μ μμ΅λλ€. μλ°μ€ν¬λ¦½νΈμλ μ£Όλ‘ μ μ μ€μ½νμ μ§μ μ€μ½ν λ κ°μ§ μ νμ μ€μ½νκ° μμ΅λλ€.
- μ μ μ€μ½ν: μ μ μ€μ½νμ μ μΈλ λ³μλ μ½λ μ΄λμμλ μ κ·Όν μ μμ΅λλ€. μ μ λ³μλ ν¨μ λ°μ΄λ μ½λ λΈλ‘ λ°μμ μ μΈλ λ³μμ λλ€.
- μ§μ μ€μ½ν: μ§μ μ€μ½νμ μ μΈλ λ³μλ ν΄λΉ ν¨μ λ΄μμλ§ μ κ·Όν μ μμ΅λλ€. ν¨μ λ΄μμ μ μΈλ λ³μλ μ§μ λ³μμ λλ€.
02. μλ°μ€ν¬λ¦½νΈ μ€μ½νμ μ’ λ₯ποΈ
1. μ μ μ€μ½ν (Global Scope)
- μ μ μ€μ½νμ μ μΈλ λ³μμ ν¨μλ μ½λ μ΄λμλ μ κ·Όν μ μμ΅λλ€.
- μ μ μ€μ½νμ λ³μλ₯Ό μ μΈν λλ var, let, constλ₯Ό μ¬μ©ν μ μμ§λ§, varλ μ μ κ°μ²΄μ μμ±μΌλ‘ μΆκ°λκ³ , letκ³Ό constλ μ μ κ°μ²΄μ μμ±μ΄ λμ§ μμ΅λλ€.
var globalVar = "I'm a global variable";
let globalLet = "I'm also global";
const globalConst = "I'm a constant global variable";
2. ν¨μ μ€μ½ν (Function Scope)
- ν¨μ μ€μ½νμ μ μΈλ λ³μλ ν΄λΉ ν¨μ λ΄μμλ§ μ κ·Όν μ μμ΅λλ€.
- varλ‘ μ μΈλ λ³μλ ν¨μ λ 벨 μ€μ½νλ₯Ό κ°μ§λ©°, ν¨μ λ΄λΆ μ΄λμλ μ κ·Ό κ°λ₯ν©λλ€.
function myFunction() {
var functionVar = "I'm inside a function";
console.log(functionVar); // μ κ·Ό κ°λ₯
}
console.log(functionVar); // μ κ·Ό λΆκ°, μ€λ₯ λ°μ
3. λΈλ‘ μ€μ½ν (Block Scope)
- λΈλ‘ μ€μ½νλ {}λ‘ κ°μΈμ§ λΈλ‘ λ΄μμλ§ λ³μκ° μ κ·Ό κ°λ₯νλλ‘ ν©λλ€.
- letκ³Ό constλ λΈλ‘ λ 벨 μ€μ½νλ₯Ό κ°μ§λ©°, λΈλ‘ λ΄λΆμμλ§ μ κ·Όν μ μμ΅λλ€.
if (true) {
let blockLet = "I'm inside a block";
const blockConst = "I'm also inside a block";
console.log(blockLet); // μ κ·Ό κ°λ₯
console.log(blockConst); // μ κ·Ό κ°λ₯
}
console.log(blockLet); // μ κ·Ό λΆκ°, μ€λ₯ λ°μ
console.log(blockConst); // μ κ·Ό λΆκ°, μ€λ₯ λ°μ
4. λͺ¨λ μ€μ½ν (Module Scope)
- μλ°μ€ν¬λ¦½νΈ ES6λΆν° λͺ¨λμ΄ λμ λλ©΄μ λͺ¨λ μ€μ½νκ° μκ²Όμ΅λλ€.
- λͺ¨λ λ΄μμ μ μΈλ λ³μμ ν¨μλ λͺ¨λ λ΄λΆμμλ§ μ κ·Ό κ°λ₯νλ©°, λ€λ₯Έ λͺ¨λμμ μ κ·Όνλ €λ©΄ λͺ μμ μΌλ‘ exportμ importλ₯Ό μ¬μ©ν΄μΌ ν©λλ€.
// module.js
export const moduleVar = "I'm in a module";
// main.js
import { moduleVar } from './module.js';
console.log(moduleVar); // "I'm in a module"
03. λ³μ μ μΈκ³Ό μ€μ½νπ
Javascript var, let, const λ³μμ κ΄ν λ΄μ©μ μλ ν¬μ€ν μ μ°Έκ³ ν΄ μ£ΌμΈμπ
var
var ν€μλλ ν¨μ μ€μ½νλ₯Ό λ°λ¦ λλ€. μ¦, ν¨μ λ΄μμ μ μΈλ λ³μλ ν¨μ λ΄ μ΄λμλ μ κ·Όν μ μμΌλ©°, λΈλ‘ μ€μ½νλ 무μλ©λλ€.
function varTest() {
if (true) {
var x = 1;
}
console.log(x); // 1 (varλ ν¨μ μ€μ½νλ₯Ό λ°λ₯΄λ―λ‘ ν¨μ λ΄λΆ μ΄λμλ μ κ·Ό κ°λ₯)
}
varTest();
μ μμμμ xλ if λΈλ‘ λ΄μμ μ μΈλμμ§λ§, ν¨μ μ€μ½νλ₯Ό λ°λ₯΄λ―λ‘ ν¨μ λ΄ μ΄λμλ μ κ·Όν μ μμ΅λλ€.
let
let ν€μλλ λΈλ‘ μ€μ½νλ₯Ό λ°λ¦ λλ€. μ¦, μ€κ΄νΈ {}λ‘ κ°μΈμ§ λΈλ‘ λ΄μμλ§ μ ν¨ν©λλ€.
function letTest() {
if (true) {
let y = 1;
console.log(y); // 1 (letμ λΈλ‘ μ€μ½νλ₯Ό λ°λ¦)
}
console.log(y); // ReferenceError: y is not defined (λΈλ‘ μΈλΆμμλ μ κ·Ό λΆκ°)
}
letTest();
μ μμμμ yλ if λΈλ‘ λ΄μμλ§ μ ν¨νλ©°, λΈλ‘ μΈλΆμμλ μ κ·Όν μ μμ΅λλ€.
const
const ν€μλλ letκ³Ό λ§μ°¬κ°μ§λ‘ λΈλ‘ μ€μ½νλ₯Ό λ°λ¦ λλ€. λν, constλ‘ μ μΈλ λ³μλ μ μΈ μ κ°μ ν λΉν΄μΌ νλ©°, μ΄νμ κ°μ λ³κ²½ν μ μμ΅λλ€.
function constTest() {
if (true) {
const z = 1;
console.log(z); // 1 (constλ λΈλ‘ μ€μ½νλ₯Ό λ°λ¦)
}
console.log(z); // ReferenceError: z is not defined (λΈλ‘ μΈλΆμμλ μ κ·Ό λΆκ°)
}
constTest();
μ μμμμ zλ if λΈλ‘ λ΄μμλ§ μ ν¨νλ©°, λΈλ‘ μΈλΆμμλ μ κ·Όν μ μμ΅λλ€. λν, constλ κ°μ μ¬ν λΉν μ μμ΅λλ€.
04. μ€μ½ν 체μΈ(Scope Chain)π
μ€μ½ν 체μΈ(Scope Chain)μ μλ°μ€ν¬λ¦½νΈμ λ³μ μ κ·Ό κ·μΉμ μ΄ν΄νλ λ° ν΅μ¬μ μΈ κ°λ μ λλ€. μ΄λ νΉμ μ€μ½ν λ΄μμ λ³μλ₯Ό μ°Ύμ§ λͺ»ν κ²½μ° μΈλΆ μ€μ½νλ‘ λ²μλ₯Ό νμ₯νλ©° λ³μλ₯Ό μ°Ύλ λ©μ»€λμ¦μ μ€λͺ ν©λλ€. μ€μ½ν 체μΈμ ν΅ν΄ μλ°μ€ν¬λ¦½νΈλ λ³μλ₯Ό κ²μνλ κ³Όμ μ λ¨κ³μ μΌλ‘ μνν©λλ€.
μ€μ½ν 체μΈμ ꡬ쑰
μ€μ½ν 체μΈμ νμ¬ μ€μ½νμμλΆν° μμνμ¬ μμ μ€μ½νλ‘ μ΄λνλ©° λ³μλ₯Ό κ²μν©λλ€. μ΄ μ²΄μΈμ μ μ μ€μ½νκΉμ§ μ΄μ΄μ§λ©°, μ μ μ€μ½νμμλ λ³μλ₯Ό μ°Ύμ§ λͺ»νλ©΄ ReferenceErrorλ₯Ό λ°μμν΅λλ€.
μμ μ½λ
μλ μμλ₯Ό ν΅ν΄ μ€μ½ν 체μΈμ΄ μ΄λ»κ² μλνλμ§ μ€λͺ νκ² μ΅λλ€.
var globalVar = "I am a global variable";
function outerFunction() {
var outerVar = "I am an outer variable";
function innerFunction() {
var innerVar = "I am an inner variable";
console.log(innerVar); // "I am an inner variable"
console.log(outerVar); // "I am an outer variable"
console.log(globalVar); // "I am a global variable"
}
innerFunction();
}
outerFunction();
μ€μ½ν 체μΈμ λμ
1. innerFunctionμ μ€μ½ν:
- innerVarλ innerFunctionμ μ§μ λ³μμ λλ€. λ°λΌμ λ°λ‘ μ°Ύμ μ μμ΅λλ€.
- outerVarλ innerFunctionμ μ€μ½νμ μμΌλ―λ‘, ν λ¨κ³ μμ μ€μ½νμΈ outerFunctionμμ μ°Ύμ΅λλ€.
- globalVarλ outerFunctionμλ μμΌλ―λ‘, μ΅μμ μ€μ½νμΈ μ μ μ€μ½νμμ μ°Ύμ΅λλ€.
2. outerFunctionμ μ€μ½ν:
- outerFunction λ΄μμλ outerVarλ₯Ό λ°λ‘ μ°Ύμ μ μμ΅λλ€.
- μ μ λ³μ globalVarλ μ°Ύμ μ μμ΅λλ€.
- νμ§λ§ innerVarλ innerFunction λ΄λΆμ λ³μμ΄λ―λ‘ outerFunctionμμλ μ κ·Όν μ μμ΅λλ€.
μ€μ½ν 체μΈμ μκ°μ νν
Global Scope
- globalVar
|
Outer Function Scope
- outerVar
|
Inner Function Scope
- innerVar
ν¨μ ν΄λ‘μ μ μ€μ½ν 체μΈ
μ€μ½ν 체μΈμ ν΄λ‘μ μ λ°μ ν κ΄λ ¨μ΄ μμ΅λλ€. ν΄λ‘μ λ ν¨μκ° μ μΈλ λμ λ μ컬 μ€μ½ν(lexical scope)λ₯Ό κΈ°μ΅νκ³ μ΄λ₯Ό μ°Έμ‘°ν μ μλ κΈ°λ₯μ λλ€.
function makeFunction() {
var name = "Mozilla";
function displayName() {
console.log(name);
}
return displayName;
}
var myFunc = makeFunction();
myFunc(); // "Mozilla"
makeFunctionμ΄ μ€νλκ³ λλ©΄ displayNameμ΄ λ°νλ©λλ€. λ°νλ ν¨μλ μ¬μ ν makeFunctionμ μ€μ½ν 체μΈμ κΈ°μ΅νκ³ μμ΄ name λ³μμ μ κ·Όν μ μμ΅λλ€. μ΄λ ν΄λ‘μ μ μ€μ½ν 체μΈμ΄ μ΄λ»κ² μνΈμμ©νλμ§λ₯Ό 보μ¬μ€λλ€.
05. νΈμ΄μ€ν (Hoisting)β¬οΈ
νΈμ΄μ€ν (Hoisting)μ μλ°μ€ν¬λ¦½νΈμμ λ³μμ ν¨μ μ μΈμ΄ κ·Έ λ²μμ 맨 μλ‘ λμ΄μ¬λ €μ§λ λμμ μλ―Έν©λλ€. μ¦, μ½λκ° μ€μ λ‘ μ€νλκΈ° μ μ λ³μμ ν¨μ μ μΈμ΄ ν΄λΉ λ²μμ 맨 μλ‘ μ΄λλ κ²μ²λΌ λμν©λλ€. κ·Έλ¬λ λ³μ ν λΉμ νΈμ΄μ€ν λμ§ μμΌλ©°, μ΄κΈ°νλ μ¬μ ν μ½λμ μλ μμΉμμ μ΄λ£¨μ΄μ§λλ€.
λ³μ νΈμ΄μ€ν
μλ°μ€ν¬λ¦½νΈλ var ν€μλλ₯Ό μ¬μ©νμ¬ μ μΈλ λ³μλ₯Ό μ€μ½νμ μ΅μλ¨μΌλ‘ νΈμ΄μ€ν ν©λλ€. κ·Έλ¬λ λ³μμ μ΄κΈ°νλ μ½λ μ€ν νλ¦μμ λ³μ μ μΈ μ΄νμ μ΄λ£¨μ΄μ§λλ€.
console.log(x); // undefined
var x = 5;
console.log(x); // 5
μ μμλ λ€μκ³Ό κ°μ΄ ν΄μλ μ μμ΅λλ€.
var x; // λ³μ μ μΈμ΄ νΈμ΄μ€ν
λ¨
console.log(x); // μ΄κΈ°νλμ§ μμμΌλ―λ‘ undefined μΆλ ₯
x = 5; // λ³μμ κ° ν λΉ
console.log(x); // 5 μΆλ ₯
letκ³Ό constμ νΈμ΄μ€ν
letκ³Ό const ν€μλλ‘ μ μΈλ λ³μλ νΈμ΄μ€ν λμ§λ§, μ΄λ€μ "μΌμμ μ¬κ°μ§λ(Temporal Dead Zone, TDZ)"μ λμ΄κ² λμ΄ μ΄κΈ°ν μ μ μ κ·Όνλ €κ³ νλ©΄ ReferenceErrorκ° λ°μν©λλ€.
console.log(y); // ReferenceError: y is not defined
let y = 10;
console.log(y); // 10
μ μμλ λ€μκ³Ό κ°μ΄ ν΄μλ μ μμ΅λλ€.
let y; // λ³μ μ μΈμ΄ νΈμ΄μ€ν
λ¨, TDZμ λ€μ΄κ°
console.log(y); // TDZμ μμΌλ―λ‘ ReferenceError λ°μ
y = 10; // TDZλ₯Ό λ²μ΄λλ©° λ³μμ κ° ν λΉ
console.log(y); // 10 μΆλ ₯
constλ λ§μ°¬κ°μ§μ λλ€.
console.log(z); // ReferenceError: z is not defined
const z = 15;
console.log(z); // 15
ν¨μ νΈμ΄μ€ν
ν¨μ μ μΈλ νΈμ΄μ€ν λ©λλ€. ν¨μ μ μ²΄κ° λμ΄μ¬λ €μ§λ―λ‘ ν¨μκ° μ μΈλκΈ° μ μ νΈμΆν μ μμ΅λλ€.
sayHello(); // "Hello, World!" μΆλ ₯
function sayHello() {
console.log("Hello, World!");
}
μ μμλ λ€μκ³Ό κ°μ΄ ν΄μλ μ μμ΅λλ€.
function sayHello() { // ν¨μ μ μΈμ΄ νΈμ΄μ€ν
λ¨
console.log("Hello, World!");
}
sayHello(); // "Hello, World!" μΆλ ₯
κ·Έλ¬λ ν¨μ ννμμ νΈμ΄μ€ν λμ§ μμ΅λλ€. λ³μ νΈμ΄μ€ν κ·μΉμ λ°λΌ μ²λ¦¬λ©λλ€.
sayGoodbye(); // TypeError: sayGoodbye is not a function
var sayGoodbye = function() {
console.log("Goodbye, World!");
};
μ μμλ λ€μκ³Ό κ°μ΄ ν΄μλ μ μμ΅λλ€.
var sayGoodbye; // λ³μ μ μΈμ΄ νΈμ΄μ€ν
λ¨
sayGoodbye(); // μ΄κΈ°νλμ§ μμμΌλ―λ‘ TypeError λ°μ
sayGoodbye = function() {
console.log("Goodbye, World!");
};
06. μ€μ½ν κ΄λ ¨ μ£Όμμ¬νβ οΈ
μλ°μ€ν¬λ¦½νΈμ μ€μ½νμ κ΄λ ¨λ μ£Όμμ¬νμ μ΄ν΄νλ©΄ μ½λ μμ±κ³Ό λλ²κΉ μ΄ ν¨μ¬ μμν΄μ§λλ€. μ€μ½νμ κ΄λ ¨λ λͺ κ°μ§ μ£Όμ μ£Όμμ¬νμ μ΄ν΄λ³΄κ² μ΅λλ€.
1. λ³μ μ μΈκ³Ό μ΄κΈ°νμ λΆλ¦¬ (var)
var ν€μλλ₯Ό μ¬μ©ν λλ λ³μ μ μΈκ³Ό μ΄κΈ°νκ° λΆλ¦¬λμ΄ μλ€λ μ μ μ£Όμν΄μΌ ν©λλ€. μ μΈμ μ€μ½νμ μ΅μλ¨μΌλ‘ νΈμ΄μ€ν λμ§λ§, μ΄κΈ°νλ μ€μ μ½λ μμΉμμ μ΄λ£¨μ΄μ§λλ€.
console.log(a); // undefined (νΈμ΄μ€ν
μΌλ‘ μΈν΄ μ μΈλ μν)
var a = 10;
console.log(a); // 10
μ μ½λλ λ€μκ³Ό κ°μ΄ ν΄μλ μ μμ΅λλ€.
var a;
console.log(a); // undefined
a = 10;
console.log(a); // 10
2. λΈλ‘ μ€μ½ν (let, const)
letκ³Ό constλ λΈλ‘ μ€μ½νλ₯Ό λ°λ₯΄λ―λ‘, μ΄λ₯Ό μ¬μ©ν λλ λΈλ‘ λ²μλ₯Ό λ²μ΄λμ§ μλλ‘ μ£Όμν΄μΌ ν©λλ€.
if (true) {
let b = 20;
const c = 30;
}
console.log(b); // ReferenceError: b is not defined
console.log(c); // ReferenceError: c is not defined
3. μ€λ³΅ μ μΈ νΌνκΈ°
letκ³Ό constλ κ°μ μ€μ½ν λ΄μμ λμΌν λ³μλͺ μ μ€λ³΅ μ μΈν μ μμ΅λλ€.
let d = 40;
let d = 50; // SyntaxError: Identifier 'd' has already been declared
const e = 60;
const e = 70; // SyntaxError: Identifier 'e' has already been declared
4. const μ¬μ© μ μ΄κΈ°ν νμ
const ν€μλλ μ μΈκ³Ό λμμ μ΄κΈ°νλ₯Ό ν΄μΌ νλ©°, μ΄νμ κ°μ λ³κ²½ν μ μμ΅λλ€.
const f; // SyntaxError: Missing initializer in const declaration
f = 80;
const g = 90;
g = 100; // TypeError: Assignment to constant variable.
5. ν¨μ μ€μ½νμ λΈλ‘ μ€μ½ν
ν¨μ μ€μ½νμ λΈλ‘ μ€μ½νμ μ°¨μ΄λ₯Ό μ΄ν΄νκ³ μμ΄μΌ ν©λλ€. varλ ν¨μ μ€μ½νλ₯Ό λ°λ₯΄κ³ , letκ³Ό constλ λΈλ‘ μ€μ½νλ₯Ό λ°λ¦ λλ€.
function scopeTest() {
if (true) {
var h = 110;
let i = 120;
}
console.log(h); // 110 (varλ ν¨μ μ€μ½νλ₯Ό λ°λ¦)
console.log(i); // ReferenceError: i is not defined (letμ λΈλ‘ μ€μ½νλ₯Ό λ°λ¦)
}
scopeTest();
6. ν΄λ‘μ μ μ€μ½ν
ν΄λ‘μ λ₯Ό μ¬μ©ν λ μΈλΆ ν¨μμ λ³μμ μ κ·Όν μ μλ€λ μ μ μ£Όμν΄μΌ ν©λλ€. μ΄λ μλνμ§ μμ λμμ μ΄λν μ μμ΅λλ€.
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter1 = createCounter();
const counter2 = createCounter();
console.log(counter1()); // 1
console.log(counter1()); // 2
console.log(counter2()); // 1 (κ° νΈμΆμ λ³λμ ν΄λ‘μ λ₯Ό λ§λ¦)
7. IIFE (μ¦μ μ€ν ν¨μ ννμ) μ¬μ©
IIFEλ λ³μλ₯Ό λΈλ‘ μ€μ½ν μμ κ°λμ΄ μ μ λ€μμ€νμ΄μ€ μ€μΌμ λ°©μ§νλ λ° μ μ©ν©λλ€.
(function() {
let j = 130;
console.log(j); // 130
})();
console.log(j); // ReferenceError: j is not defined
8. ν¨μ λ΄λΆμμμ var
ν¨μ λ΄λΆμμ varλ₯Ό μ¬μ©ν λλ ν¨μ μ 체μ κ±Έμ³ λ³μκ° μ ν¨νλ€λ μ μ μ£Όμν΄μΌ ν©λλ€. μ΄λ μλμΉ μμ λ³μ μΆ©λμ μ΄λν μ μμ΅λλ€.
function example() {
for (var k = 0; k < 5; k++) {
// do something
}
console.log(k); // 5 (루νκ° λλ νμλ kλ μ ν¨ν¨)
}
example();
9. μ μ κ°μ²΄μ μμμ μ μ
λ³μλ₯Ό μ μΈνμ§ μκ³ μ¬μ©νλ©΄ μ μ κ°μ²΄μ νλ‘νΌν°λ‘ μμμ μ μΈμ΄ λ©λλ€. μ΄λ₯Ό νΌνκΈ° μν΄ νμ var, let, constλ₯Ό μ¬μ©ν΄ λ³μλ₯Ό μ μΈν΄μΌ ν©λλ€.
function implicitGlobal() {
l = 140; // μμμ μ μ λ³μ
}
implicitGlobal();
console.log(l); // 140 (μ μ λ³μλ‘ μμ±λ¨)