[JS] This의 Binding 5가지
해당 블로깅은 인프런의 강의를 들으며 공부한 내용을 정리한 글입니다.
ES5 기준 핵심 내용을 공부하면서 작성하는 블로깅
This Binding
이 일어나는 시점은?
- 실행 컨텍스트가 활성화 될 때 바인딩이 발생한다
- 컨텍스트에 대한 게시글은 앞의 게시물에서 정리했다.
- 실행 컨텍스트는 해당 컨텍스트를 지닌 함수가 호출될 때 실행
그렇다면 해당 컨텍스트를 지닌 함수를 어떻게 호출하냐에 따라 This
가 바인딩되는 대상이 다르다.
- 전역공간에서의
this
- 함수 호출시의
this
- 메서드 호출시의
this
callback
호출시의this
- 생성자함수(constructor)호출시의
this
위처럼 실행컨텍스트가 호출되는 방법에 따라 this
는 다르게 바인딩이 된다.
전역에서 호출시
this
는 전역객체를 가르킨다.
브라우저에서는 window
노드에서는 global
이 this
가 된다.
윈도우 객체
글로벌 객체
함수 호출시
함수 호출했을 때에도 this
는 전역 객체를 가르킨다.
왤까?? 함수는 전역공간에서 호출을한다. 그렇다면 함수에서 this
는 전역공간에서의 this
가 될것이고 전역 공간의 this
는 전역 객체이기 때문이다.
함수로써 호출했을 때의 this
여기서 함수 내부에서 또 다른 내부함수를 정의하여 해당 내부 함수에서 console을 확인했을때도this
는 전역 객체가 나온다. 이것은 창시자의 실수 또는 자바스크립트의 성격이라고 볼 수 있으며, ES6에서는arrow function
문법이 존재하고, 바인딩을 하지않으면 바로 위에있는 컨텍스트의this
를 가져온다. 하지만,
ES5의 환경(함수 선언식)에서 함수로써 호출되었을 때this
는 전역객체가 된다.
메서드 내에서 함수로 호출 할 때의 this
var test = { a: function() { function b() { console.log(this); } b(); } } test.a();
위를 호출하면
this
는 전역 객체이다.
this
를 출력하는 것은b
라는 이름을 가진함수
이다.
ES5환경에서 함수로 호출은this
가 전역 객체를 의미한다.
this
가 바인딩 될때 호출되는 방법이 어떤지를 보면 쉽게 확인할 수 있다.
메서드 호출시
메서드로 호출시에는 this
가 바인딩 되는 대상은 메서드를 호출하는 대상이 this
로 바인딩 된다.(a.b()
라고 했을때 b
메서드를 호출하는 a
객체가 this
가 된다)
1)
a
객체의 메서드를 호출시 메서드에서this
는a
가 된다.
2)
a
객체 안의b
객체의 메서드인c
를 호출하면 메서드에서this
는.c()
앞의b
객체가 된다.
내부 함수에서 this 우회법
var a = 10; var obj = { a: 20, b: function() { console.log(this.a); function c() { console.log(this.a); } c(); } } obj.b();
콘솔에서 가르키는
this.a
는 각각 20과 10이 출력된다.
그 이유는obj.b()
를 호출할때this
는 메서드로써 호출됨으로 호출하는 객체가this
가 되어obj.a
인 20을 출력한다.
하지만c()
에서 호출하는this
는 메서드가 아닌 함수로써 호출임으로this
는 전역객체가 된다. 그래서window.a
를 출력하게 되고, 특이하게 전역객체서 선언된var a
의 값인 10을 출력한다. 이 부분은 자바스크립트의 특이성인데 전역 컨텍스트에 선언된 변수는 전역 객체의 프로퍼티가 된다.
그럼 여기 내부함수에서 this
를 b
와 같이 obj
라는 객체를 가르키기 위해서 어떤방법을 사용하면 좋을까?
var a = 10; var obj = { a: 20, b: function() { var self = this; // 여기서 self라는 변수에 this맵핑 console.log(this.a); function c() { console.log(self.a); // 맵핑된 self변수를 통해 출력 } c(); } } obj.b();
위 처럼
this
를 내부에서 다른 변수에 맵핑을 하여 해당 변수를 이용하면 내부 함수에서도 호출을 할 수 있다.
콜백함수 호출시
콜백함수에서 this
는 여러가지가 있지만, 기본적으로는 전역객체를 바인딩한다고 생각하면 된다. 하지만 call
, apply
, bind
메서드를 통해 this
를 바인딩 한다면, 전역객체가 아닌 바인딩 되는 다른 무언가가 this
가 될것이다.
var callback = function() { console.dir(this); }; var obj = { a: 1, b: function(cb) { cb(); } }; obj.b(callback);
위에서의
this
는 전역객체이다.
앞에서 다 알아봤듯이 cb를 실행하는 시점에서는 그냥 함수를 실행한 것이고, ES5에서는 함수를 실행할때 this는 전역객체이다.
그래서 콜백함수로 호출이 되어도 기본적으로this
는 전역객체지만var callback = function() { console.dir(this); }; var obj = { a: 1, b: function(cb) { cb.call(this); } }; obj.b(callback);
위에서 매개변수로 입력받은 콜백함수를
call
메서드를 통해서this
를obj
로 바인딩해주고 호출을 한다.
b라는 메서드 내에서this
는obj
이기 때문이다.
이처럼this
를 바인딩을 따로 해주지 않는 이상 전역객체를 바라본다.마지막으로
setTimeout
에서의this
바인딩 예제를 보자.var callback = function() { console.dir(this); }; var obj = { a: 1 }; setTimeout(callback, 100);
위의 코드에서
callback
함수가 호출되면 콘솔에는window
전역객체가 찍힌다.
하지만
callback
함수의this
를obj
로 바인딩해준다면?var callback = function() { console.dir(this); }; var obj = { a: 1 }; setTimeout(callback.bind(obj), 100);
위 처럼
this
는obj
로 바인딩되어 찍힌다.
생성자함수 호출시
생성자는 new
키워드를 통하여 새로운 인스턴스를 생성할때 호출된다.
이 때는 새로 생성되는 인스턴스 자체가 this
가 된다.
function Person(name, age) { this.name = name; this.age = age; } var quokka = new Person('quokka', 29); console.log(quokka);
위 코드를 실행할 때
Person
의this
는new
키워드를 통해서 인스턴스를 생성할때 생성자로 호출되기때문에this
가 생성되는 인스턴스인quokka
가 되고 내부에서quokka.name = 'quokka', quokka.age = 29
로 지정이 되는것이다.
Author And Source
이 문제에 관하여([JS] This의 Binding 5가지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@wldns12378/JS-This의-Binding-5가지저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)