loading

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

첫번째(1) 부터 보는걸 권장한다.

 

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(바인딩 규칙 예외)

 

 

 

 

4가지 규칙에 대한 몇 가지 예외가 있다.

이 바인딩 동작은 다른 바인딩을 의도했지만 결과가 다른 바인딩 동작으로 

 

1. this가 무시될 때

null 또는 undefined를 this 바인딩 매개변수로 전달하여 call/apply 할 때 해당 값이 효과적으로

무시되고 대신 기본 바인딩 규칙이 적용된다.

 

예)

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

var a = 2;

A.call( null ); // 2

명시적 바인딩인 call을 이용하여 함수 호출을 한다.

하지만 null을 넣어서 호출했기 때문에 기본 바인딩의 규칙으로 실행한다.

그러므로 결과 값은 2

 

 

2. 기본 함수 개체에 대한 참조

기본 함수 개체를 참조했을 때 기본 바인딩 규칙이 적용된다.

 

예)

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

var a = 2;
var o = { a: 3, fn: A };
var p = { a: 4 };

o.fn(); // 암시적 바인딩 결과 값 : 3

(p.fn = o.fn)(); // 기본 바인딩 결과 값 : 2

이 경우를 봐보자. 여기서 헷갈릴 수도 있다. 이 예제는 암시적 바인딩 규칙이 적용돼야 하는 거 아닌가?

라는 의문을 가진다.

 

하지만 아니다 기본 바인딩 규칙이 적용된다.

이유를 살펴보자.

 

우선 o.fn() 이건 암시적 바인딩이 맞다.

그리고 두 번째 (p.fn = o.fn)(); 이 구문을 봐보자.

 

o.fn 이 함수를 p.fn 에게 할당하고 있다.

이 부분에서 엇! 그럼 p.fn이라 이것도 암시적 바인딩이라서 결과 값은 4가 나와야 하는 거 아냐?

라는 착각을 할 수도 있다.

 

이유는?

 

A(); 이것과 (p.fn = o.fn)(); 이게 동일하냐고 궁금할 것이다.

p.fn = o.fn 할당 구문과 동시에 (); 이 함수를 호출하고 있어서 그런 거다...

그래서 기본 바인딩 규칙으로 적용되고 있는 것이다.

 

만약 이것을

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

var a = 2;
var o = { a: 3, fn: A };
var p = { a: 4 };


//(p.fn = o.fn)();

p.fn = o.fn;
p.fn(); // 결과 값은 4

위 코드로 적용 시에 암시적 바인딩 규칙으로 적용이 된다.

이게 원했던 그림인가? 그렇다면 p.fn = o.fn이라는 할당을 완전히 한 후에

p.fn(); 이렇게 실행을 해야 암시적 바인딩으로 된다.

 

암튼 여기서는 할당 구문을 동시에 함수 호출을 하면 기본 바인딩으로 적용된다는 점 유의하자.

 

반응형

 

3. ES6에서의 arrow 함수 안에서 this 참조

ES6에서부터 나오는 arrow 함수 => 이렇게 표현되는 함수 안에서의 this는 일반 함수의 4가지 규칙에서 예외다. 

예를 봐보자.

 

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

var obj1 = {
    a: 2
};

var obj2 = {
    a: 3
};


var bar = A.call( obj1 );
  bar.call( obj2 ); // 무엇이 찍힐까?

마지막 부분 bar.call(obj2); 이 부분은 무엇일 찍힐까? 3이라고 생각하면 틀렸다.

2가 찍힌다. 그 이유는?

 

var bar = A.call( obj1 ); 이 구문을 실행할 때, A 함수가 obj1 객체를 바인딩했고,

그럼 A 함수 안에서는 this의 참조가 obj1이다.

 

근데 이 A 함수 안에 this는 obj1를 참조 중에 있고 arrow 함수가 생성이 되었는데

이때 arrow 함수의 this는 A함수의 this를 참조한다.

그래서 arrow 함수 안에 this는 obj1를 참조하고 있다.

 

이제 헷갈리는 부분을 설명한다.

bar.call( obj2 ) ; <--- 이 구문이다. 분명 bar.call이라는 명시적으로 obj2를 직접적으로 바인딩을 넣어놨는데

왜 arrow 함수 안에는 obj2 가 아닌 obj1을 참조를 할까?

 

arrow 함수는 한 번 정의된 바인딩에 대해선 다시 재정의 할 수가 없기 때문이다.

즉, 이미 한번 obj1에 바인딩이 되었기 때문에,

bar.call를 사용하여 obj2를 직접적으로 바인딩을 시도해도 안 먹히는 것이다.

그래서 결과 값은 2가 나오는 것.

반응형

+ Recent posts