티스토리 뷰

JavaScript의 변수 선언 방식 비교 : var, let, const

1. var

  • 스코프(Scope): 함수 스코프
  • 호이스팅(Hoisting): 변수 선언이 최상단으로 끌어올려짐, 초기화 전에는 undefined
  • 재선언 가능: 동일 스코프 내에서 여러 번 재선언 가능

예제:

function exampleVar() {
    console.log(x); // undefined (호이스팅 발생)
    var x = 10;
    console.log(x); // 10

    var x = 20; // 재선언 가능
    console.log(x); // 20
}
exampleVar();

2. let

  • 스코프(Scope): 블록 스코프
  • 호이스팅(Hoisting): 호이스팅되지만 초기화는 선언 위치에서 이루어짐, 초기화 전 접근 시 ReferenceError
  • 재선언 불가: 동일 스코프 내에서 재선언 불가

예제:

function exampleLet() {
    console.log(y); // ReferenceError: y is not defined (초기화 전 접근 불가)
    let y = 10;
    console.log(y); // 10

    // let y = 20; // SyntaxError: Identifier 'y' has already been declared (재선언 불가)
}
exampleLet();

3. const

  • 스코프(Scope): 블록 스코프
  • 호이스팅(Hoisting): 호이스팅되지만 초기화는 선언 위치에서 이루어짐, 초기화 전 접근 시 ReferenceError
  • 재선언 및 재할당 불가: 재선언 및 값 재할당 불가, 객체와 배열의 내부 프로퍼티나 요소는 수정 가능

예제:

function exampleConst() {
    const z = 10;
    console.log(z); // 10

    // z = 20; // TypeError: Assignment to constant variable (재할당 불가)
    
    const obj = { name: 'Alice' };
    obj.name = 'Bob'; // 객체의 내부 프로퍼티는 수정 가능
    console.log(obj.name); // 'Bob'
    
    // const z = 30; // SyntaxError: Identifier 'z' has already been declared (재선언 불가)
}
exampleConst();

요약

  • var: 함수 스코프, 호이스팅 발생(초기화 전 undefined), 재선언 가능
  • let: 블록 스코프, 호이스팅 발생(초기화 전 ReferenceError), 재선언 불가
  • const: 블록 스코프, 호이스팅 발생(초기화 전 ReferenceError), 재선언 및 재할당 불가 (객체/배열의 내부 수정 가능)

이 예제들을 통해 각 키워드의 특성과 동작 방식을 보다 명확하게 이해할 수 있습니다. let과 const는 var보다 안전하고 예측 가능한 코드 작성을 가능하게 합니다.

 

this 키워드의 사용과 그 특성

this 키워드는 함수가 호출되는 방식에 따라 this가 참조하는 값이 달라집니다.

this는 주로 객체의 메서드나 함수 내부에서 사용되며, 현재 문맥에서의 객체를 가리킵니다.

 

1. 전역 컨텍스트(Global Context)에서의 this

  • 브라우저 환경: this는 전역 객체인 window를 가리킴
  • Node.js 환경: this는 전역 객체인 global을 가리킴

2. 함수 컨텍스트(Function Context)에서의 this

  • 일반 함수:
    • 기본적으로 전역 객체를 가리킴 (window 또는 global)
  • 엄격 모드(Strict Mode):
    • this는 undefined로 설정됨

3. 메서드 호출 시의 this

  • 메서드 내부: 메서드를 호출한 객체를 가리킴

4. 생성자 함수(Constructor Function)에서의 this

  • 새로 생성된 객체를 가리킴
  • 생성자 함수 내부에서 this를 사용해 새 객체의 프로퍼티를 설정

5. bind, call, apply 메서드를 통한 this 조작

  • call과 apply:
    • 첫 번째 인자로 전달된 객체를 this로 설정하여 함수 호출
  • bind:
    • this가 고정된 새로운 함수를 반환

6. 화살표 함수(Arrow Function)에서의 this

  • 렉시컬 스코프를 사용하여 상위 스코프의 this를 상속받음
  • 화살표 함수는 자신이 정의된 위치의 this를 그대로 사용
  1.  

예제

// 전역 컨텍스트에서의 this
console.log(this); // 브라우저에서는 window, Node.js에서는 global 객체

// 함수 컨텍스트에서의 this
function exampleFunction() {
    console.log(this); // 일반 모드: window (브라우저), 엄격 모드: undefined
}
exampleFunction();

// 메소드 호출시의 this
const obj = {
    name: 'Alice',
    greet: function() {
        console.log(this.name); // 'Alice'
    }
};
obj.greet();

// 생성자 함수에서의 this
function Person(name) {
    this.name = name;
}
const person1 = new Person('Bob');
console.log(person1.name); // 'Bob'

// bind, call, apply 메서드를 통한 this 조작
function showName() {
    console.log(this.name);
}
const obj1 = { name: 'Charlie' };
const obj2 = { name: 'Dave' };

showName.call(obj1); // 'Charlie'
showName.apply(obj2); // 'Dave'

const boundFunction = showName.bind(obj1);
boundFunction(); // 'Charlie'

// 화살표 함수에서의 this
const obj = {
    name: 'Eve',
    regularFunction: function() {
        setTimeout(function() {
            console.log(this.name); // undefined, 전역 객체를 참조
        }, 1000);
    },
    arrowFunction: function() {
        setTimeout(() => {
            console.log(this.name); // 'Eve', 화살표 함수는 외부 스코프의 this를 사용
        }, 1000);
    }
};
obj.regularFunction();
obj.arrowFunction();

요약

  • 전역 컨텍스트: this는 전역 객체(window 또는 global)를 가리킴.
  • 함수 컨텍스트: 일반 함수에서는 전역 객체, 엄격 모드에서는 undefined.
  • 메서드 호출: this는 메서드를 호출한 객체를 가리킴.
  • 생성자 함수: this는 새로 생성된 객체를 가리킴.
  • bind, call, apply: this를 특정 객체로 설정하여 함수 호출.
  • 화살표 함수: this는 상위 스코프의 this를 그대로 사용.

이와 같이, this는 함수가 호출되는 방식에 따라 참조하는 객체가 달라지며, 이를 정확히 이해하는 것이 JavaScript에서 중요한 개념입니다.

렉시컬 스코프(Lexical Scope)의 개념과 그 특성

렉시컬 스코프(Lexical Scope)는 프로그래밍 언어에서 변수가 정의된 위치에 따라 그 변수를 사용할 수 있는 범위가 결정되는 개념을 의미합니다. 이 스코핑 방식은 코드가 작성된 위치, 즉 소스 코드의 구조에 따라 변수의 유효 범위가 결정됩니다.

1. 렉시컬 스코프(Lexical Scope)란?

  • 정의: 변수가 정의된 위치에 따라 유효 범위가 결정되는 스코핑 규칙
  • 다른 이름: **정적 스코프(Static Scope)**라고도 불림
  • 중요성: 함수가 호출된 위치가 아닌, 정의된 위치를 기준으로 변수의 유효 범위가 결정됨

2. 렉시컬 스코프의 주요 특성

  • 정적 결정:
    • 변수가 어떤 스코프에 속하는지는 코드가 작성된 시점에 결정됨
    • 함수가 어디서 호출되든, 해당 함수가 정의된 위치에 따라 변수를 찾음
  • 스코프 체인(Scope Chain):
    • 함수 내부에서 변수를 찾을 때, 먼저 자신의 스코프에서 찾고, 없으면 외부 스코프로 거슬러 올라가면서 찾음
    • 이 과정이 스코프 체인을 형성
  • 클로저(Closure)와의 관계:
    • 클로저는 렉시컬 스코프 덕분에 가능
    • 함수가 외부 함수의 변수에 접근할 수 있게 해주며, 함수가 호출된 이후에도 그 변수를 "기억"함

3. 렉시컬 스코프 예제

function outer() {
    let outerVar = 'I am outside!';

    function inner() {
        console.log(outerVar); // 'I am outside!' 출력
    }

    inner();
}
outer();
  • 설명:
    • inner 함수는 outer 함수 내에서 정의되었기 때문에, outerVar에 접근할 수 있음
    • inner 함수가 호출될 때, outerVar를 찾기 위해 스코프 체인을 따라 outer 함수의 스코프를 참조

4. 렉시컬 스코프의 장점

  • 예측 가능성: 코드의 구조에 따라 변수의 유효 범위를 쉽게 예측할 수 있음
  • 가독성 향상: 변수가 어디서 사용될 수 있는지가 명확해지므로, 코드의 이해와 유지보수가 용이함
  • 클로저 사용 가능: 클로저를 통해 변수의 상태를 유지하면서 비동기 작업이나 이벤트 처리 등에 활용 가능

요약

  • 렉시컬 스코프는 변수가 정의된 위치에 따라 유효 범위가 결정되는 스코핑 규칙
  • 스코프 체인을 통해 내부 함수는 외부 함수의 변수에 접근 가능
  • 클로저는 렉시컬 스코프 덕분에 변수의 상태를 유지하며 사용 가능

이와 같이, 렉시컬 스코프는 함수와 변수가 어떤 관계를 가지는지를 명확하게 정의하여 코드의 예측 가능성과 안정성을 높여줍니다.