4 min to read
JS This
Javascript This에 대한 개념 정리
This?
Pic1. Mozilla 사이트에 정의된 thisJavascript를 처음접하는 사람들은 this라는 용법에 대해 매우 혼란스러워 할수가 있다. 이유는 여러가지가 있을 수 있지만, 보통 다른 언어와 다르게 this가 사용된다는 점과 strict mode일때와 아닐때 this는 다르게 사용되기 때문에 어려울 수 있다. 대부분의 경우 this 는 함수의 호출하는 방법에 의해 결정된다. 이 말을 좀 더 쉽게 풀이하면,
What is this? this === 호출한 (실행한) 객체
좀 더 자세히 설명하면 this는 4가지 함수실행 타입이 존재하기 때문에, 각각의 타입에 따른 이해가 필요하다. 함수 실행 : alert(“hello world”); 메소드 실행: console.log(“hello world”); 생성자 실행: new Array(“1”); 간접 실행: someFunction.call(undefined, ‘hello world’); / apply
이뿐만 아니라 엄격모드 (‘use strict’)에 따라 다른 영향을 미친다.
- 함수 실행
var someone = {
name: "kingsae",
whoAmI: function () {
console.log(this);
},
};
var myWhoAmI = someone.whoAmI;
myWhoAmI(); // window
함수실행에 있어서 this는 전역객체이다. 이유는 실행한 시점에서 실행될때 window.myWhoAmI 로 전역객체를 참조하고 있기 때문이다. 여기서 엄격모드(use strict)를 하게 되면 실행문맥은 더이상 전역객체로 사용되지 않기 때문에 undefined로 만든다.
var person = {
personA: 5,
personB: 10,
whoAreYou: function () {
console.log(this === person); // => true
function whoAmI() {
// this는 window, 엄격 모드였으면 undefined
console.log(this === person); // => false
return this.personA + this.personB;
}
return whoAmI();
},
};
person.whoAreYou(); // NaN, 엄격 모드였으면 TypeError
우리가 실수를 많이 하는 부분은 person.whoAreYou()를 실행시킬때 (메소드실행) , whoAreYou내부에 this는 person을 가르킬것이다. 그래서 whoAmI를 실행할때 당연히this는 person을 가르키고있을 것이라 판단한다. 하지만 whoAmI는 함수실행, 즉 이 함수의 전역객체인 window가 된다. 이를 해결하기 위해선 call 메소드를 이용하여 메소드실행 방식으로 호출하게 되면 문제를 해결할수 있다.
var person = {
personA: 5,
personB: 10,
whoAreYou: function () {
console.log(this === person); // => true
function whoAmI() {
console.log(this === person); // => true
return this.personA + this.personA;
}
// 문맥을 수정하기 위해 .call() 메소드를 적용
return whoAmI.call(this);
},
};
person.whoAreYou(); // => 15
- 메소드 실행
var someone = {
name: "kingsae",
whoAmI: function () {
console.log(this);
},
};
someone.whoAmI(); // someone
위에도 잠시 언급했지만 메소드실행은 함수실행과 다르다. 그 이유는 서로 다른 타입이기 때문이다. 메소드 실행은 함수내에 있는 function Property를 호출하는 반면에 함수실행은 속성접근자를 이용하지않고 바로 호출한다. 메소드 실행은 메소드를 소유하고 있는 객체가 this가 된다.
var someone = {
name: "kingsae",
whoAmI: function () {
console.log(this);
},
};
someone.whoAmI(); // someone;
var btn = document.getElementById("bnt");
btn.addEventListener("click", someone.whoAmI);
특정함수내에 메소드를 넘겨 실행할때, 우리는 someone.whoAmI가 샐행될 것이라고 생각한다. 하지만 함수 실행처럼 this는 window가 반환된다. 이유는 someone.whoAmI를 넘겼지, 실행한것이 아니기 때문에 마치 상위에 예제 처럼 myWhoAmI를 호출한것과 같다.
이를 해결하기 위해 변동되는 this를 고정시키기면 된다. bind함수를 사용하게 되면 해당 객체 this를 강제로 bind시킬 수 있다. 3. 생성자 실행 생성자 실행에서 this는 새롭게 만들어진 객체이다. 생성자 실행은객체에 초기값을 셋팅하기 위해 사용된다.
function Foo() {
console.log(this instanceof Foo); // => true
this.property = "Default Value";
}
// 생성자 실행
var fooInstance = new Foo();
fooInstance.property; // => 'Default Value' 4. 간접 실행
자바스크립에서 call, apply를 이용하면, 첫번째 매개변수로 this를 받는다
function increment(number) {
return ++number;
}
increment.call(undefined, 10); // => 11
increment.apply(undefined, [10]); // => 11
javascript개발자라면 console.log(this);를 디버깅하면서 자주 사용하게 된다 ㅎㅎ 위와 같이 this에 대해 알고 있다 하더라도 말이다. 그래도 위와 같이 개념을 잘 정립하고 개발한다면 조금이나마 헷갈리는 this를 잘 사용할 수 있지 않을까 생각된다.
Comments