loading

JS - javascript 에서의 this 를 정확히 알아보자 링크

  1. JS - javascript 에서의 this 를 정확히 알아보자 - 1(기본 바인딩)
  2. JS - javascript 에서의 this 를 정확히 알아보자 - 2(암시적 바인딩)
  3. JS - javascript 에서의 this 를 정확히 알아보자 - 3(명시적 바인딩)
  4. JS - javascript 에서의 this 를 정확히 알아보자 - 4(new 바인딩)
  5. JS - javascript 에서의 this 를 정확히 알아보자 - 5(4가지 규칙 우선순위)
  6. JS - javascript 에서의 this 를 정확히 알아보자 - 6(바인딩 규칙 예외)

 

 

 

자바스크립트는 다른 언어와 다르게 this에 관련된 부분이 많은 개발자들에게 혼란을 준다.

나 또한 그랬다.

 

이 this를 사용 하려고하면 내가 알고 있는 지식만으로 이해하기 힘들었다.

이 this 가 참조하고 있는 것이 내가 생각하고 있는 것과 달랐다고 해야 하나?

 

암튼 모호하게 알고 있으면 안 될 것 같아 이렇게 남겨본다.

우선 자바스크립트 this를 얘기하전에 자바스크립트 코드가 어떤 형식으로 실행

되는지를 먼저 알아야 한다.

 

 

자바스크립트 코드를 읽고 실행하는 주체를 그냥 엔진이라고 표현하겠다.

 

A라는 함수가 있다고 가정하자.

function A(){
  console.log(this);
}

A();

이 함수를 A(); 이렇게 호출하면 엔진은 실행 콘텍스트라고 하는 메모리? 기록된 곳?

실행하려고 하는 함수의 순서로 저장된(활성화된) 어떠한 장소(메모리)? 

 

암튼 이런 의미를 담고 있는 무엇인가를 생성하게 된다.

이 무엇인가가 스택(Stack) 형태로 쌓여 있는데 가볍게 이것을 활성화된 레코드라 부르겠다.

 

이 레코드에는 함수가 호출된 위치, 함수가 호출된 방법,

전달된 매개변수 등에 대한 정보가 포함되어져 있다. 

레코드의 속성 중 하나가 바로 this 참조 이다. 

 

이 this는 A라는 함수가 실행되는 동안 사용하게 된다.

그럼 이 A라는 함수는 this에 어떻게 바인딩이 되었는지,

 

쉽게 말에 이 A라는 함수가 this라는 참조를 어떻게 하는지 이해하려면

호출 사이트 (Call-Site)를 알아야 한다. 


호출 사이트(Call-Site) : 코드에서 함수가 호출되는 위치.

호출 사이트가 무엇인지 간단하게 코드 예제를 통해서 설명하겠다.

예)

function start() {
    // 호출된 스택 : start
    // 호출된 사이트는 전역범위에 있음
    console.log( "start" );
    A(); // <- A에 대한 호출 사이트
}

function A() {
    // 호출된 스택 :  start -> A
    // 호출된 사이트는 start
    console.log( "A" );
    B(); // <-- B에 대한 호출 사이트
}

function B() {
    // 호출된 스택 :  start -> A -> B
    // 호출된 사이트는 A
    console.log( "B" );
}

start(); // <- start에 대한 호출 사이트

 

this 에 바인딩에 4가지(기본 바인딩, 암시적 바인딩, 명시적 바인딩, new 바인딩) 규칙이 있는데,

이 4가지 규칙 중 호출 사이트에 적용될 수 있는 우선순위를 결정하고,

 

해당하는 규칙이 결정이 되면 함수는 4가지 규칙 중에 한 가지 규칙으로 this에 참조를 하게 되는데,

이때의 순간 자체를 호출 사이트가 결정한다.

말이 어렵다.

 

쉽게 말해, 4가지 규칙이 있는데 호출사이트 행동 자체가 이 4가지 중 한 가지를

우선 순으로 결정하여 한 가지 규칙을 정해서 this를 참조하게 한다라고 생각하면 된다.

 

 

반응형

 

1. 기본 바인딩(default Binding)

일반적인 함수 호출의 경우인 독립 실행형 함수 호출 유형에서 비롯된다.

이러한 기본 바인딩으로 호출된 함수의 this는 전역 개체를 가리킨다.

 

중요 : 기본 바인딩으로 호출된 함수의 this는 전역개체를 가리킨다.

기본 바인딩으로 호출된 함수의 this는 전역 개체를 가리킨다. 이유 없다 외우자!

아래처럼 실행되는 유형의 함수는 모두 기본바인딩!!

// 기본바인딩 함수호출 예제
function A() {
    console.log( this.a );
}

var a = 2;

A(); // 2

이 코드를 실행하게 되면 결과는 2가 나온다 왜일까?

위 설명한 대로 기본 바인딩 함수 호출에 적용되므로 this 가 전역 개체를 참조하고 있고,

전역 번수인 var a는 2의 값을 담고 있으니까

 

A 함수 안에서의 this.a 는 전역 함수를 가리켜서 2의 값이 나온다. 

여기서 우린 이 자바스크립트 코드가 비 엄격 모드(non-strict mode)로 실행이 되었다는 걸

잊으면 안 된다.

 

다음 내용에 넘어가기 앞서 엄격 모드(strict mode) 와

비 엄격 모드(non-strict mode - 비엄격모드는 sloppy mode 라고 부르기도 한다.) 의 내용을

먼저 알아야 한다.

 

엄격모드(strict mode), 비엄격모드(non-strict mode)

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Strict_mode

 

Strict mode - JavaScript | MDN

엄격 모드는 평범한 JavaScript 시멘틱스에 몇가지 변경이 일어나게 합니다.

developer.mozilla.org

 

 

 

자 이번엔 엄격 모드에서 실행해보자.

function A(){
  'use strict';
  
  console.log(this.a);
}

var a = 2;

A();

실행결과

결과는 에러다. A 함수 안에 'use strict' 엄격 모드가 선언이 되어있다.

이런 경우 this는 전역 개체를 참조를 하지 않는다.

 

즉, 전역 부분과 A라는 함수와 엄격하게 구분한다.

그래서 에러를 발생하게 된다.

 

 

자 이번엔 다른 예를 통해서 알아보자.

function A(){ 
  console.log(this.a);
}

var a = 2;


(function(){
  'use strict'; // 엄격선언
  A(); // 2 <-- A 에 대한 호출 사이트
  
})();

이 경우를 보면 엇? 할 거다.

즉시 실행 함수에 엄격 모드를 선언했고, A() 함수를 호출했는데 에러가 발생하지 않고 실행이 잘 된다.

결괏값은 2.

 

왜 그럴까? 바인딩 규칙은 전적으로 호출 사이트를 기반으로 설정되지만,

위 함수를 보면 즉시 실행 함수 안에 엄격 모드를 선언했지만,

 

A(); 함수의 호출 사이트는 A이므로 A 자체 함수에 엄격 모드가 선언되지 않으면

A함수의 this는 전역 객체를 참조한다. 

 

말이 어려운데,

실행되는 함수 자체(A)가 엄격 모드가 아니면 this는 전역 객체를 참조한다.

 

이처럼 엄격모드/비 엄격모드는 개발을 할 때, 어떤 코드 부분은 의도적으로 엄격모드로 선언했다가,

어떤 코드의 함수 부분은 비엄격으로 해놨다가 하면 내가 예상치 못하는 일들이 벌어질 것이다.

 

그러므로 개발하기 앞서 엄격/ 비엄격 둘 중 하나를 기준으로 잡고 모든 전체 코드가 동일하게 적용된 상태에서 개발을 해야 한다.

 

이렇게 기본 바인딩에 대해서 공부했다. 다음엔 남은 3가지 규칙마저 진행해야겠다.

 

 

 

반응형

+ Recent posts