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

 

 

 

명시적 바인딩은 암시적 바인딩의 의미가 반대라고 생각하면 된다.

암시적 바인딩은 어떠한 함수의 this 참조가 호출 사이트로 인해 간접적으로 바인딩해야 했다.

 

하지만 명시적 바인딩은 말 그대로 직접적으로 명확하게 어떠한 객체를 참조하라!!라는

의미를 부여해서 this가 어떠한 객체를 참조하게 하는 의미이다.

 

명시적 바인딩을 설명하기 앞서 몇 가지 알고 넘어가야 한다.

그중 하나는 자바스크립트는 함수도 객체라는 것과,

자바스크립트에는 프로토타입이라는 게 존재하는 것

 

이 두 가지를 알고 넘어가야 한다.

지금 명시적 바인드를 설명하기엔 저 두 가지를 자세히 알 필요가 현재는 없고,

그냥 있다는 것만 알면 된다.

 

프로토타입에 관련된 자세한 내용을 알고 싶으면 아래 사이트에서 확인하면 된다.

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

 

Function - JavaScript | MDN

Function 생성자는 새 Function 객체를 만듭니다. 이 생성자를 직접 호출하여 동적으로 함수를 생성할 수도 있으나, 보안 문제 및 eval과 유사한(그러나 훨씬 덜 심각한) 성능 문제가 발생할 수 있습니

developer.mozilla.org

 

일반적으로 개발자들이 function AAA(){} 라는 함수를 만들면,

즉, function 키워드를 사용하여, 함수를 만들면 이 함수에는 내가 선언하지 않았지만

프로토타입 메서드가 들어있다.

 

위 사이트 가면 여러 정보를 얻을 수 있지만 메서드를 자주 사용하는 3개만 말하자면

apply(), bind(), call() 메서드가 대표적이다.

 

그래서 함수를 일반적로 AAA(); 이렇게 사용을 하지만

apply, bind, call을 이용하여 함수 호출도 가능하다.

 

호출 예시)

일반 호출 : AAA();

프로토타입 메서드를 사용하여 호출 : AAA.apply(); AAA.bind(); AAA.call();

 

이런 식으로 호출이 가능하다.

프로토타입의 메서드를 사용하여 함수 호출을 할 때 매개변수를 받는데,

 

구문 예시로 AAA.call(this, 인자 값); 이렇다.

bind, apply은 두 번째 매개변수가 다르니 MDN 사이트 들어가면

 

엠디엔 사이트 펑션 프로토타입 메서드
MDN 사이트 function 메서드

 

자세한 설명과 함께 되어있으니 꼭 확인해보자.

 

이렇듯 프로토 타입에 있는 메서드를 사용하여 함수를 호출하면 this를 지정할 수 있어서

명시적 바인딩에 해당한다. 이게 무슨 뜻이냐면 아래 예제를 통해서 알아보자.

 

예시 코드를 보자.

/* 
// 의문 궁금점 - 1
function A(_this){
	return _this.a;
}
*/

function A() {
    return this.a;
}

var obj = {
    a: 2
};

var result = A.call( obj );

console.log(result); // 2

 

이 코드를 보면 일반 함수 A를 만들어서 함수 호출하는 코드이다.

A라는 함수를 일반적으로 호출하지 않고 call이라는 걸 붙여서 호출을 한다.

프로토타입의 메서드를 이용해서 호출을 하고 있는데

 

 

매개변수에 obj라는 객체를 넣어서 함수를 호출하고 있다.

그런데 이상하다?

일반적으로 함수 호출을 사용만 했던 개발자라면 지금 이 상황이 이해가 안 될 것이다.

 

A 함수에는 매개변수로 아무것도 받을 만한?

인자 값이 없다?

 

이상하지 않은가?

저 코드의 주석 처리된 '의문 궁금점 - 1' 부분의 코드를 예상하지 않았는가?

 

그렇다 이렇게 사용하는건 그냥 일반적인 함수 사용 호출 방법이고,

call을 붙여서 사용하면 그 의미는 달라진다.

 

call 메서드를 이용하여 A함수를 호출하는데 obj라는 객체를 매개변수에 넣어서 호출하면

 

 A.call(obj);   이렇게 호출하면

 

명시적으로 A 함수에게 obj 객체의 this를 지정해주는 것이다.

다시말해 이 this는 무엇을 참조해주는가? 바로 매개변수 obj 객체를 넣었던 obj 자체를 의미한다.

 

그래서 A 함수 내에서 this는 obj가 되는 것이다.

자 이미지로 다시 설명해본다.

 

명시적 바인딩

 

A 함수는 아무 인자도 안 받지만 프로토타입 메서드를 이용하여

객체를 넣어서 호출을 하게 되면 즉, A.call(obj); 이렇게 호출하게 되면

 

저 A라는 함수 안에서의 this는 obj라는 객체를 참조하게 된다.

이게 바로 명시적 바인딩이다.

 

테스트를 진행해보면 아래 코드를 복사해서 테스트를 진행해보자.

function A() {
    console.log(this); // 무엇이 찍힐까?
}

var obj = {
    a: 2
};

A.call( obj );

무엇이 찍힐까?

바로 obj 객체가 찍힌다..

 

즉, 아까 말한 obj 객체의 자신을 참조하게 된다.

그래서 A 함수에서의 this는 obj 가 된다.

 

암시적 바인딩은 이전 글에서도 설명해놨지만 호출 사이트로 인해 this 값이 암시적으로 지정되고,

혹은 또 호출 사이트로 인해 도중에 this참조가 바뀌는 반면에,

 

명시적 바인딩은 저렇게 직접적으로 this에 이 객체를 참조해라!라는

직접적으로 지정을 해주기 때문에 암시적 바인딩과는 차이점이 있다.

 

 

자 이제는 좀 더 난이도가 있는 예제를 살펴보자.

function A(something) {
    console.log( this.a, something ); // 어느 값이 찍힐 까? - 1
    return this.a + something;
}

var obj = {
    a: 2
};

var B = function() {
    return A.apply( obj, arguments );
};

var temp = B( 3 );
console.log( temp ); // 어느 값이 찍힐 까? - 2

 

위 코드에선 console.log 부분에 어떤 값이 찍히는지 고민해보자.

여기서 알아야 할 것은? arguments라는 것을 모르면 코드를 해석하기 어렵다.

 

이전 글 arguments객체에 대해 참조하자.

https://knowing-passion.tistory.com/34

 

JS - arguments 객체 란 무엇?

이 arguments 객체가 무엇일까? 이 arguments 객체는 MDN 사이트에서 정의하는 글을 인용하자면, https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/arguments arguments 객체 - JavaScr..

knowing-passion.tistory.com

 

어느 값이 찍힐 가? - 1 : 2, 3

어느 값이 찍힐 가? - 2 : 5

 

이렇게 값이 찍힌다.

이 예제는 B(3)이라는 일반 함수 호출을 하고 있는데,

 

이 B라는 함수 안에 A라는 함수의 프로토타입인 apply를 이용하여 함수를 호출하고 있는데

이때 this의 인자를 obj 객체를 명시적으로 넣어서 호출을 하고 있다.

 

만약 이게 암시적이었다면 this 참조가 바뀌는데

이 처럼 명시적으로 obj를 직접적으로 참조를 하게 지정하면 그 지정한 객체를 참조하게 된다.

 

 

반응형

+ Recent posts