본문으둜 κ±΄λ„ˆλ›°κΈ°

Javascript Essentials πŸ₯š

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 기초적인 문법과 κ°œλ…μ„ μ‚΄νŽ΄λ΄…λ‹ˆλ‹€.

'use strict'​

ES5(2009)μ—μ„œ μ†Œκ°œλœ κΈ°λŠ₯으둜, 단어 κ·ΈλŒ€λ‘œ JSμ—μ„œ 엄격 λͺ¨λ“œλ₯Ό ν™œμ„±ν™”μ‹œν‚΅λ‹ˆλ‹€. λ°˜λ“œμ‹œ μ†ŒμŠ€ μ΅œμƒλ‹¨μ— μœ„μΉ˜ν•΄μ•Όν•˜λ©°, ν™œμ„±ν™”λœ 엄격λͺ¨λ“œλŠ” λΉ„ν™œμ„±ν™” ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

μ•„λž˜ 예제λ₯Ό μ‚΄νŽ΄λ΄…μ‹œλ‹€.

"use strict";

function strictModeExample() {
a = 123; // 엄격λͺ¨λ“œμ—μ„œλŠ” μ „μ—­ μŠ€μ½”ν”„ λ³€μˆ˜ μ„ μ–Έ λΆˆκ°€λŠ₯
}

strictModeExample(); // ReferenceError: a is not defined
function nonStrictModeExample() {
a = 123;
}

nonStrictModeExample(); // OK
console.log(a); // 123

이처럼 μ „μ—­ μŠ€μ½”ν”„ λ³€μˆ˜ 선언이 λΆˆκ°€λŠ₯ν•˜λ„λ‘ λ§‰μŠ΅λ‹ˆλ‹€.

엄격λͺ¨λ“œμ˜ κΈ°λŒ€νš¨κ³ΌλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

  1. 였λ₯˜ 감지 ν–₯상: 일반적으둜 λ¬΄μ‹œλ˜λŠ” μ—λŸ¬λ“€μ„ μ‹€μ œ 였λ₯˜λ‘œ 처리
  2. μ•ˆμ „ν•œ μ½”λ”©: μ‹€μˆ˜λ‘œ μ „μ—­ λ³€μˆ˜λ₯Ό μƒμ„±ν•˜λŠ” 것을 방지
  3. μ„±λŠ₯ μ΅œμ ν™”: 엔진이 μ½”λ“œ μ΅œμ ν™”λ₯Ό 더 효과적으둜 μˆ˜ν–‰
  4. ν–₯ν›„ λ²„μ „μ˜ JSμ™€μ˜ ν˜Έν™˜μ„±: ν–₯ν›„ λ²„μ „μ—μ„œ κΈˆμ§€λ  κΈ°λŠ₯듀을 미리 κΈˆμ§€

μŠ€μ½”ν”„μ™€ λ³€μˆ˜ 선언​

μŠ€μ½”ν”„(Scope)​

  1. μ „μ—­ μŠ€μ½”ν”„ (Global Scope):
    • 전체 슀크립트 μ–΄λ””μ„œλ‚˜ μ ‘κ·Ό κ°€λŠ₯ν•©λ‹ˆλ‹€.
  2. 지역 μŠ€μ½”ν”„ (Local Scope):
    • νŠΉμ • μ˜μ—­ λ‚΄μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯ν•©λ‹ˆλ‹€.
    • 지역 μŠ€μ½”ν”„λŠ” 2κ°€μ§€λ‘œ λ‚˜λ‰©λ‹ˆλ‹€.
      • ν•¨μˆ˜ μŠ€μ½”ν”„ (Function Scope): ν•¨μˆ˜ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λ“€μ€ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯ν•©λ‹ˆλ‹€. var둜 μ„ μ–Έλœ λ³€μˆ˜κ°€ 여기에 ν•΄λ‹Ήν•©λ‹ˆλ‹€.
      • 블둝 μŠ€μ½”ν”„ (Block Scope): {}둜 λ‘˜λŸ¬μ‹ΈμΈ 블둝 λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λ“€μ€ ν•΄λ‹Ή 블둝 λ‚΄μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯ν•©λ‹ˆλ‹€. letκ³Ό const둜 μ„ μ–Έλœ λ³€μˆ˜κ°€ 여기에 ν•΄λ‹Ήν•©λ‹ˆλ‹€.

ν•¨μˆ˜ μŠ€μ½”ν”„μ™€ 블둝 μŠ€μ½”ν”„λ₯Ό λͺ…ν™•νžˆ μ΄ν•΄ν•˜κΈ° μœ„ν•œ μ˜ˆμ œμ½”λ“œμž…λ‹ˆλ‹€.

function functionScopeExample() {
if (true) {
var functionScopedVar = "hello";
}
console.log(functionScopedVar); // "hello"
}

functionScopeExample();
console.log(typeof functionScopedVar); // 'undefined' (ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œλŠ” μ ‘κ·Όν•  수 μ—†μŒ)
function blockScopeExample() {
if (true) {
let blockScopedLet = "μ €λŠ” 블둝 μŠ€μ½”ν”„μž…λ‹ˆλ‹€";
const blockScopedConst = "저도 블둝 μŠ€μ½”ν”„μž…λ‹ˆλ‹€";
console.log(blockScopedLet); // "μ €λŠ” 블둝 μŠ€μ½”ν”„μž…λ‹ˆλ‹€"
console.log(blockScopedConst); // "저도 블둝 μŠ€μ½”ν”„μž…λ‹ˆλ‹€"
}
// console.log(blockScopedLet); // μ—λŸ¬: blockScopedLet은 블둝 λ‚΄μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯
// console.log(blockScopedConst); // μ—λŸ¬: blockScopedConstλŠ” 블둝 λ‚΄μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯
}

blockScopeExample();

varλ₯Ό μ‚¬μš©ν•œ κ²½μš°μ—λŠ” 블둝 μŠ€μ½”ν”„κ°€ μ•„λ‹Œ ν•¨μˆ˜ μŠ€μ½”ν”„μ΄κΈ° λ•Œλ¬Έμ— ifλ¬Έ(블둝 μŠ€μ½”ν”„) λ°–μ—μ„œλ„ 접근이 κ°€λŠ₯ν•©λ‹ˆλ‹€.

ν‚€μ›Œλ“œ 없이 μ„ μ–Έ 및 μ΄ˆκΈ°ν™”β€‹

  • μ „μ—­ 레벨 μŠ€μ½”ν”„(Global-level scope)
  • ν˜Έμ΄μŠ€νŒ…λ˜μ§€ μ•ŠμŒ
  • 엄격λͺ¨λ“œμ—μ„œ μ‚¬μš©λΆˆκ°€
  • μž¬μ„ μ–Έ 및 μž¬ν• λ‹Ή κ°€λŠ₯

μ•„λž˜ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ΄…μ‹œλ‹€.

// console.log(foo); // ReferenceError: foo is not defined

(function () {
foo = 1;
})();

console.log(foo); // 1

ν˜Έμ΄μŠ€νŒ…λ˜μ§€ μ•Šμ•„ ν•¨μˆ˜ μ‹€ν–‰ μ „μ—λŠ” foo에 μ ‘κ·Όν•  수 μ—†μ§€λ§Œ, μ‹€ν–‰λœ μ΄ν›„μ—λŠ” μ „μ—­ μŠ€μ½”ν”„μ— λ³€μˆ˜κ°€ μ„ μ–Έλ˜μ–΄ 접근이 κ°€λŠ₯ν•©λ‹ˆλ‹€.

var​

  • ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„(Function-level scope): varλŠ” ν•¨μˆ˜ λ‚΄μ—μ„œ μ„ μ–Έλ˜λ©΄ ν•¨μˆ˜ μ „μ²΄μ—μ„œ, ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œ μ„ μ–Έλ˜λ©΄ μ „μ—­ μŠ€μ½”ν”„μ—μ„œ μœ νš¨ν•©λ‹ˆλ‹€.
  • ν˜Έμ΄μŠ€νŒ…: μ„ μ–Έλœ μœ„μΉ˜μ™€ 상관없이 ν•¨μˆ˜μ˜ μ΅œμƒλ‹¨μœΌλ‘œ ν˜Έμ΄μŠ€νŒ…λ©λ‹ˆλ‹€. 단, λ³€μˆ˜ μ΄ˆκΈ°ν™” 값은 ν˜Έμ΄μŠ€νŒ… λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • μž¬μ„ μ–Έ κ°€λŠ₯: 같은 μŠ€μ½”ν”„ λ‚΄μ—μ„œ λ³€μˆ˜λ₯Ό μ€‘λ³΅ν•˜μ—¬ μ„ μ–Έν•  수 μžˆμŠ΅λ‹ˆλ‹€.
function varExample() {
console.log(x); // undefined (ν˜Έμ΄μŠ€νŒ…μœΌλ‘œ 인해)
var x = 5;
console.log(x); // 5
}
varExample();

console.log(y); // undefined (ν˜Έμ΄μŠ€νŒ…μœΌλ‘œ 인해)
if (true) {
var y = 10;
}
console.log(y); // 10 (ν•¨μˆ˜ μ™ΈλΆ€μ΄λ―€λ‘œ μ „μ—­ μŠ€μ½”ν”„)

let​

  • 블둝 레벨 μŠ€μ½”ν”„(Block-level scope)
  • ν˜Έμ΄μŠ€νŒ…: let도 ν˜Έμ΄μŠ€νŒ…λ˜μ§€λ§Œ, μ„ μ–Έλœ 라인 μ΄μ „μ—μ„œ μ ‘κ·Όν•˜λ € ν•˜λ©΄ μ°Έμ‘° μ—λŸ¬(Reference Error)κ°€ λ°œμƒν•©λ‹ˆλ‹€. 이λ₯Ό "μΌμ‹œμ  μ‚¬κ°μ§€λŒ€(Temporal Dead Zone, TDZ)"라고 ν•©λ‹ˆλ‹€.
  • μž¬μ„ μ–Έ λΆˆκ°€λŠ₯: 같은 μŠ€μ½”ν”„ λ‚΄μ—μ„œλŠ” μž¬μ„ μ–Έν•  수 μ—†μŠ΅λ‹ˆλ‹€.
  • μž¬ν• λ‹Ή κ°€λŠ₯: μž¬ν• λ‹Ήμ€ κ°€λŠ₯ν•©λ‹ˆλ‹€.
function letExample() {
// console.log(a); // μ°Έμ‘° μ—λŸ¬: aκ°€ μ΄ˆκΈ°ν™”λ˜μ§€ μ•ŠμŒ (TDZ)
let a = 3;
console.log(a); // 3
// let a = 4; // μ—λŸ¬: 'a'κ°€ 이미 선언됨
a = 5; // μž¬ν• λ‹Ή κ°€λŠ₯
console.log(a); // 5
}

letExample();

if (true) {
let b = 20;
}
// console.log(b); // μ—λŸ¬: bλŠ” 블둝 μŠ€μ½”ν”„ λ‚΄μ—μ„œλ§Œ 유효

const​

  • 블둝 레벨 μŠ€μ½”ν”„: const도 let처럼 블둝 레벨 μŠ€μ½”ν”„λ₯Ό κ°–μŠ΅λ‹ˆλ‹€.
  • κ°’ λ³€κ²½(μž¬ν• λ‹Ή) λΆˆκ°€: μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™”ν•΄μ•Ό ν•˜λ©°, ν•œ 번 ν• λ‹Ήλœ 값을 λ³€κ²½ν•  수 μ—†μŠ΅λ‹ˆλ‹€.
  • μž¬μ„ μ–Έ λΆˆκ°€λŠ₯: letκ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ 같은 μŠ€μ½”ν”„ λ‚΄μ—μ„œ μž¬μ„ μ–Έν•  수 μ—†μŠ΅λ‹ˆλ‹€.

varλŠ” μ™œ 쓰지 μ•Šμ„κΉŒ?​

varλŠ” μœ„μ—μ„œ μ‚΄νŽ΄λ³ΈλŒ€λ‘œ ν˜„λŒ€μ μΈ μ½”λ”© μŠ€νƒ€μΌμ— λ§žμ§€ μ•ŠλŠ” νŠΉμ§•μ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ let, constλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹κ² μŠ΅λ‹ˆλ‹€.

μ΄μœ λŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€:

  1. 블둝 레벨 μŠ€μ½”ν”„(Block-level Scope): μ΄λŠ” μ½”λ“œ 블둝 λ°–μ—μ„œλ„ λ³€μˆ˜μ— μ ‘κ·Όν•  수 있게 ν•˜μ—¬ μ˜λ„μΉ˜ μ•Šμ€ 문제λ₯Ό μΌμœΌν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.
  2. ν˜Έμ΄μŠ€νŒ… 방지: μ„ μ–Έ 전에 μ ‘κ·Όν•˜λ©΄, undefinedλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. μ΄λŠ” 디버깅을 μ–΄λ ΅κ²Œ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.
  3. μž¬μ„ μ–Έ 방지: 같은 μŠ€μ½”ν”„ λ‚΄μ—μ„œ μž¬μ„ μ–Έμ΄ κ°€λŠ₯ν•˜μ—¬ ν˜Όλž€μ„ μ΄ˆλž˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  4. μ½”λ“œμ˜ 가독성과 μœ μ§€λ³΄μˆ˜μ„± ν–₯상: letκ³Ό const의 μ‚¬μš©μ€ μ½”λ“œμ˜ 가독성과 μœ μ§€λ³΄μˆ˜μ„±μ„ ν–₯μƒμ‹œν‚΅λ‹ˆλ‹€. λ³€μˆ˜μ˜ μŠ€μ½”ν”„κ°€ λͺ…ν™•ν•˜κ³ , μž¬μ„ μ–Έ 및 변경이 μ œν•œλ¨μœΌλ‘œμ¨ μ½”λ“œμ˜ 예츑 κ°€λŠ₯성이 λ†’μ•„μ§‘λ‹ˆλ‹€.

ν˜Έμ΄μŠ€νŒ…κ³Ό TDZ​

JSμ—μ„œλŠ” ν˜Έμ΄μŠ€νŒ…(hoisting)μ΄λΌλŠ” λ©”μ»€λ‹ˆμ¦˜μ΄ μž‘λ™ν•˜λŠ”λ°, μ΄λŠ” λ³€μˆ˜μ™€ ν•¨μˆ˜ 선언이 그듀이 ν¬ν•¨λœ λ²”μœ„μ˜ μ΅œμƒλ‹¨μœΌλ‘œ λŒμ–΄μ˜¬λ €μ§„ κ²ƒμ²˜λŸΌ μž‘λ™ν•œλ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€. 단, 이 κ³Όμ •μ—μ„œ λ³€μˆ˜μ˜ μ΄ˆκΈ°ν™”λŠ” ν˜Έμ΄μŠ€νŒ…λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ•„λž˜ μ˜ˆμ‹œ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ΄…μ‹œλ‹€:

(function () {
console.log(num); // μ—¬κΈ°μ„œ `num`을 호좜

var num = 1; // `num` λ³€μˆ˜ μ„ μ–Έκ³Ό μ΄ˆκΈ°ν™”
})();

ν˜Έμ΄μŠ€νŒ…μ˜ κ΄€μ μ—μ„œ 이 μ½”λ“œλŠ” λ‹€μŒκ³Ό 같이 ν•΄μ„λ©λ‹ˆλ‹€:

  1. var num 선언이 ν•¨μˆ˜ λ²”μœ„μ˜ μ΅œμƒλ‹¨μœΌλ‘œ ν˜Έμ΄μŠ€νŒ…λ©λ‹ˆλ‹€.
  2. console.log(num)이 싀행될 λ•Œ, num은 이미 μ„ μ–Έλ˜μ—ˆμ§€λ§Œ 아직 값이 ν• λ‹Ήλ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
  3. λ”°λΌμ„œ num은 undefined μƒνƒœμž…λ‹ˆλ‹€.
  4. 이후 num = 1이 μ‹€ν–‰λ˜λ©΄μ„œ num에 1이 ν• λ‹Ήλ©λ‹ˆλ‹€.

μžλ£Œν˜•(Data type)​

크게 2가지 μžλ£Œν˜•μœΌλ‘œ λ‚˜λ‰©λ‹ˆλ‹€

  • μ›μ‹œ νƒ€μž…(Primitive Types)
  • 객체(Object)

μ›μ‹œ νƒ€μž…(Primitive Types)​

  1. Number: 123, 0.45
  2. String: 예: 'hello', "world"
  3. Boolean: true, false
  4. Undefined: let a;
  5. Null: typeof null은 objectμ§€λ§Œ, μ΄λŠ” JS μ΄ˆκΈ°μ„€κ³„μ— 있던 λ²„κ·Έμž…λ‹ˆλ‹€. 예: let a = null;
  6. Symbol: ES6μ—μ„œ μΆ”κ°€λœ νƒ€μž…μœΌλ‘œ, κ³ μœ ν•˜κ³  λ³€κ²½ λΆˆκ°€λŠ₯ν•œ 데이터 νƒ€μž…μž…λ‹ˆλ‹€. 주둜 객체 μ†μ„±μ˜ ν‚€λ‘œ μ‚¬μš©λ©λ‹ˆλ‹€.
  7. BigInt: 맀우 큰 μ •μˆ˜λ₯Ό λ‚˜νƒ€λ‚Ό λ•Œ μ‚¬μš©λ˜λŠ” νƒ€μž…μž…λ‹ˆλ‹€. 숫자 뒀에 n을 λΆ™μ—¬ μ‚¬μš©ν•©λ‹ˆλ‹€. 예: 12345678901234567890n

객체(Object)​

  • Object: 데이터와 κ·Έ 데이터에 κ΄€λ ¨λœ λ™μž‘μ„ κ·Έλ£Ήν™”ν•˜λŠ” μ»¨ν…Œμ΄λ„ˆμž…λ‹ˆλ‹€. κ°μ²΄λŠ” 킀와 κ°’μ˜ 쌍으둜 κ΅¬μ„±λ©λ‹ˆλ‹€. 예: { name: "Alice", age: 30 }
  • νŠΉλ³„ν•œ ν˜•νƒœμ˜ 객체듀도 μ‘΄μž¬ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ λ°°μ—΄(Array), ν•¨μˆ˜(Function), λ‚ μ§œ(Date), μ •κ·œν‘œν˜„μ‹(RegExp) 등이 μžˆμŠ΅λ‹ˆλ‹€.

typeof null === typeof object?​

10μΌλ§Œμ— λ§Œλ“€μ–΄μ§„ JS의 μ΄ˆκΈ°κ΅¬ν˜„ λ²„κ·Έμž…λ‹ˆλ‹€. 32λΉ„νŠΈ 쀑 첫 3λΉ„νŠΈλŠ” κ°’μ˜ νƒ€μž…μ„ κ²°μ •ν•˜λŠ” 데 μ‚¬μš©λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이 μ‹œμŠ€ν…œμ—μ„œ null은 λͺ¨λ“  λΉ„νŠΈκ°€ 0으둜 μ„€μ •λœ μœ μΌν•œ κ°’μ΄μ—ˆκ³ , κ°μ²΄λŠ” νƒ€μž… λΉ„νŠΈλŠ” 000μ΄μ˜€μŠ΅λ‹ˆλ‹€.

이 버그가 μˆ˜μ •λ λ•Œ μƒκΈ°λŠ” 영ν–₯을 μ˜ˆμΈ‘ν•  수 μ—†μ–΄, μ§€κΈˆκΉŒμ§€ μˆ˜μ •λ˜μ§€ μ•Šκ³  μžˆμŠ΅λ‹ˆλ‹€.

| 참고: 링크

undefined vs null​

typeof null; // "object" (not "null" for legacy reasons)
typeof undefined; // "undefined"
null === undefined; // false
null == undefined; // true
null === null; // true
null == null; // true
!null; // true
Number.isNaN(1 + null); // false
Number.isNaN(1 + undefined); // true

typeof function(){} === 'function'​

function은 μ—„λ°€νžˆλŠ” κ°μ²΄μž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ typeof μ—°μ‚°μžλŠ” function을 function으둜 λ°˜ν™˜ν•©λ‹ˆλ‹€. ν•¨μˆ˜μ— μ „λ‹¬λœ μΈμžκ°€ νŠΉμ • ν•¨μˆ˜μΈμ§€ 확인할 λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€. APIλ‚˜ 라이브러리λ₯Ό λ§Œλ“€ λ•Œ μ‚¬μš©μžκ°€ μ œκ³΅ν•œ 콜백 ν•¨μˆ˜κ°€ μ‹€μ œλ‘œ ν•¨μˆ˜ νƒ€μž…μΈμ§€ κ²€μ¦ν•˜λŠ” 데 μœ μš©ν•©λ‹ˆλ‹€.