this 와 this 바인딩
js는 흔히들 난해한 언어라고들 한다.
초보들도 쉽게 이해하기 위해 몇 가지 설계를 타 언어들과 조금 다르게 했다는데
그 점이 오히려 난해하게 된 이유라고 한다.(난 그냥 어렵다.)
오늘은 그중에 하나인 this를 정리하겠다.
this
자바스크립트에서 this는 기본적으로 실행 컨텍스트가 생성될 때 함께 결정된다.
그리고 실행 컨텍스트는 함수를 호출할 때 생성된다.
즉 this는 함수를 호출할때 결정된다.
상황에 따라 this가 어떤 값을 보게 되는지 알아보자
전역 공간에서의 this
간단하다 전역 공간에서 this는 전역 객체를 가리킨다.
브라우저에서는 window Node.js에서는 global이다.
console.log(this); // window, global
console.log(this === window) // true
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
// js에서 모든 변수는 결국 특정 객체의 프로퍼티로써 동작하기 때문에 this.a 가 1을 가리키게 된다.
메서드에서의 this
메서드란 객체의 프로퍼티에 할단된 함수로써 그 메서드를 호출 할 때 메서드로써 작동을 한다. 즉 그냥 사용하면 메서드가 아니다.
let func = function(x){
console.log(this, x);
}
func(1); // window{} 1
let obj = {
method: func
}
obj.method(2) // {method:f} 2
위 코드에서 똑같이 func라는 함수를 호출했으나 결과가 달랐다. 그 차이는 '.'의 유무이다. (혹은 대괄호)
즉 객체의 프로퍼티로 할당된 함수를 사용하는 방식이 메서드이고 그 차이가 this를 달리 바라보게 만드는 원인이다.
구분 자체는 쉽지만 this라는 말 자체가 조금 난해해졌다.
기왕이면 호출 주체가 없더라도 this가 자동으로 주변 환경을 바라봤으면 좋겠다.
다음은 그 방법들이다.
// 상위 스코프의 this를 그대로 활용 가능한 화살표 함수
var obj = {
outer: function(){
console.log(this); // outer
var innerFunc = () => {
console.log(this); // outer
}
innerFunc();
}
}
obj.outer();
call 메서드
call 메서드는 메서드의 호출 주체인 함수를 즉시 실행하도록 하는 메서드다.
이때 call 메서드의 첫 번째 인자를 this로 바인딩 하게 되는데 이를 이용하여 임의의 객체를 this로 지정할 수 있다.
var func = function(a, b, c){
console.log(this, a, b, c);
}
func(1, 2, 3) // window{} 1 2 3
func.call({x: 1}, 4, 5, 6) // {x: 1} 4 5 60
apply 메서드
apply 메서드는 call 메서드와 기능적으로 완전히 동일하다.
둘 다 메서드는 첫 번째 인자를 제외 한 나머지 모든 인자들을 호출 할 함수의 매개변수로 지정하나 변수로 일일히 지정하느냐 혹은 배열로 묶어주느냐의 차이다.
var func = function(a, b, c){
console.log(this, a, b, c);
}
func.apply({x: 1}, [4,5,6]); // { x: 1 } 4 5 6
var obj = {
a: 1,
method: function (x, y){
console.log(this.a, x, y);
}
}
obj.method.apply({a: 4}, [5, 6]); // 4 5 6
bind 메서드
call과 비슷하나 넘겨 받은 this 및 인수를 바탕으로 새로운 함수를 반환하기만 할 뿐인 함수다. 즉 this를 미리 적용하고 부분 적용 함수를 구현하는 두 가지 목적을 가진 메서드다.
책이나 다른 사이트에서 나온 내용인데 솔직히 한 눈에 읽히나? 난 아닌데 하지만 예제를 보면 어떨까
var func = function(a,b,c,d){
console.log(this, a, b, c, debug)
}
func(1,2,3,4); // window{} 1 2 3 4
var bindFunc1 = func.bind({ x:1 });
bindFunc1(5,6,7,8); //{ x: 1} 5 6 7 8
var bindFunc2 = func.bind({ x: 1 }, 4, 5);
bindFunc2(6, 7); // { x: 1 } 4 5 6 7
bindFunc2(8, 9); // { x: 1 } 4 5 8 9
call, apply, bind 메서드 활용
다음은 내부 함수에 상위 컨텍스트의 this를 전달하는 방법이다.
// call
var obj = {
outer: function(){
console.log(this); // outer
var innerFunc = function(){
console.log(this); // outer
};
innerFunc.call(this);
}
}
obj.outer();
// bind
var obj = {
outer: function(){
console.log(this); // outer
var innerFunc = function(){
console.log(this); // outer
}.bind(this);
innerFunc();
}
}
obj.outer();
정리
- this는 전역공간에서는 전역 객체를 참조한다
- 어떤 함수를 메소드로써 호출할 경우 this는 그 메서드의 호출 주체를 참조한다
- 함수로써 호출 할 경우 this는 전역 객체를 참조한다.
- 생성자 함수에서의 this는 생성될 인스턴스를 참조한다.
- call, applly 메서드를 활용하면 this를 명시적으로 지정이 가능하며 함수 또는 메서드를 호출한다.
- bind 메서드를 활용하면 this 및 함수에 넘길 인자를 일부를 지정한 새로운 함수를 리턴해준다.
Author And Source
이 문제에 관하여(this 와 this 바인딩), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yhlee1227/this-와-this-바인딩저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)