자바스크립트의 this
this 키워드
this는 다음과 같이 object 점연산자(.)의 왼쪽에 있는 object에 바운드 됩니다. 마치 매개변수와도 같다고 생각하면 쉽게 이해 됩니다. 매개변수이긴 한데 암묵적으로 인수가 넘겨지는 것이지요.
var fn = function(a, b){
console.log(this);
};
var obj = {
fn: function (a, b){
console.log(this);
}
};
var ob1 = {
method : obj.fn
};
var ob2 = {
method : fn
};
ob1.method(4,5);
ob1['method'](4,5);
ob2.method(1,2);
obj.fn(3, 4);
{ method: [Function: fn] }
{ method: [Function: fn] }
{ method: [Function: fn] }
{ fn: [Function: fn] }
ob1['method'](4,5)
는 ob1.method(4,5)
와 같은 표현입니다.
다양한 상황에서 this 키워드
var fn = function(one, two){
console.log(this, one, two);
};
var r = {red : 'red'};
var g = {green : 'green'};
var b = {blue : 'blue'};
var y = {yellow : 'yellow'};
위와 같이 함수와 object가 있을때
첫째
r.method = fn;
r.method(g,b);
{ red: ‘red’, method: [Function: fn] } { green: ‘green’ } { blue: ‘blue’ }
r.method의 점 왼쪽 robject가 this에 바운드 되었습니다.
둘째
fn(g, b);
이경우 점연산자도 없고 따라서 점왼쪽에 있는 object가 뭔지 알 수 없지만 자바스크립트는 default로 global object를 this에 바운드 시킵니다.
노드에서 실행하면
{ console: [Getter], …(중략)… setTimeout: { [Function: setTimeout] [Symbol(util.promisify.custom)]: [Function] } } { green: ‘green’ } { blue: ‘blue’ }
이런 결과가 나오고 크롬 브라우저의 콘솔에서 실행하면
Window {postMessage: ƒ, blur: ƒ…(중략)… {green: “green”} {blue: “blue”}
이런 결과가 나옵니다 두 환경에서 global object는 다른가 봅니다.
셋째
함수가 object의 property는 아니지만 (메소드는 아니지만) this에 특정 object를 바인드 시키고 싶을때가 있다고 합니다.
fn.call(r,g,b);
위와 같이 call메소드를 호출하여 첫번째 매개변수로 object를 주면 this는 그 object에 바운드 됩니다.
{ red: ‘red’, method: [Function: fn] } { green: ‘green’ } { blue: ‘blue’ }
이미 어떤 object의 property라고 해도 call을 사용하면 this에 다른 object를 바운드 시킬 수 있습니다.
r.method.call(y, g, b);
{ yellow: ‘yellow’ } { green: ‘green’ } { blue: ‘blue’ }
넷째
callback으로 넘겨진 fn과 r.method
setTimeout(fn, 1000);
setTimeout(r.method, 1000);
이경우도 node에서의 실행과 크롬브라우저에서의 실행 결과가 조금 다릅니다. 노드에서는 Timeout object가 this에 바운드 되고
Timeout { _called: true, _idleTimeout: 1000, _idlePrev: null, _idleNext: null, _idleStart: 73, _onTimeout: [Function: fn], _timerArgs: undefined, _repeat: null, _destroyed: false, [Symbol(asyncId)]: 4, [Symbol(triggerAsyncId)]: 1 } undefined undefined
크롬 브라우저에서는 global object가 this에 바운드됩니다.
Window {postMessage: ƒ, blur: ƒ…(중략)… undefined undefined
다섯째
inline function expression을 사용하여 선언된 함수 내부의 경우
setTimeout(function(){
r.method(g, b)
}, 1000);
{ red: ‘red’, method: [Function: fn] } { green: ‘green’ } { blue: ‘blue’ }
명확하게 점 연산자 다음 r객체가 있습니다.
여섯째
new r.method(g,b);
new 키워드는 새로운 object를 만들기 때문에 this는 이 새로운 object에 바운드 된다고 합니다. 그런데 앞에 붙는 fn은 무슨 의미인지 모르겠네요
fn {} { green: ‘green’ } { blue: ‘blue’ }
예전에 제가 작성했던 gist문서입니다. 열심히 써놓고 깜빡하고 있었네요 https://gist.github.com/gwnuysw/4c1ea3e9be9adb11381c62ef3bdc6acc