This 키워드
자바스크립트의 정말 헷갈리는 개념이자 정말 중요한 개념 중 하나인 This 키워드!
한마디로 This를 정의하자면,
This는 호출 시점에서 실행함수가 가르키는 객체이다. 다른말로는 실행함수의 호출자. 라고 할 수 있을 것 같다.
자바스크립트에는 4가지 Pattern이 있는데, 일반함수 실행, 메소드 실행, 생성자 (new) 실행, 명시적 지정(call, apply, bind ) 이 그것이다.
일반함수 실행
함수실행에서의 This는 전역객체(window)이다.
function add(x, y) {
console.log(this);
return x + y;
}
add(3, 4);
// window -> add()에서 this는 전역객체(window)
// 7
그렇다면, 아래 코드를 실행한 후 result 값은 무엇이 될까?
var x = 10;
var add = function(y) {
var x = 20;
return this.x + y;
};
result = add(10); // 20
add() 함수 내에서 새로 선언된 x=20; 때문에 답이 30이라고 생각할 수 있지만, 실행시점에서 this는 window이다. 또한, 자바스크립트에서 변수는 함수 스코프를 가지므로, 함수 실행시점에서 x는 전역에서 선언된 10이되고, result = 20이다. (add 함수 내에 console.log(x); 를 하면, 20이 찍힐 것이다.)
메소드 실행
메소드란, 객체의 속성으로 정의된 함수이다. 이 경우, This는 해당 메소드를 소유하고 있는 객체가 된다.
var obj = {
foo: function() {
console.log(this);
}
};
// obj
생성자(new) 실행
생성자는 new 로 객체를 만드는 것이고, 이 때, this는 new를 통해 만들어 진 새로운 변수이다.
function Human(name, hobby) {
this.name = name;
this.hobby = hobby;
this.newThis = function() {
return this;
};
}
const aHuman = new Human("Steve", "Swimming"); //new로 Human 객체 생성
aHuman.newThis(); // Human
명시적 지정
.call()이나, .apply(), .bind()를 이용하여 This를 명시적으로 지정해줄 수 있다. .bind()는 이후 새 포스팅을 통해 소개하도록 하고, 이번엔 .call()과 .apply()만 다루고자 한다. .call()과 .apply()의 역할은 동일하나, .apply()는 배열/유사배열을 인자로 받는다는 것이 다르다.
func.call(thisArg, arg1, arg2…) / func.apply(thisArg, [arg1, arg2…])
여기서 thisArg 자리에 명시적으로 지정해줄 This 객체를 적으면 된다. 이 때의 This는 명시적으로 지정해준 This이다.
var obj1 = {
foo: function() {
console.log(this);
}
};
var obj2 = {
foo: obj1.foo
};
obj1.foo.call(obj2); // obj2
obj1의 foo 함수를 실행하지만, call을 이용하여, this가 obj2 임을 지정해 주었기 때문에 this는 obj2이다.
코딩을 하다보면 This의 늪에 빠지게 되어, 범인은 또 This야!! 라고 울컥울컥 하기도 하지만, 자바스크립트의 유연성을 대표하는 매력적인 키워드 인것 같다. 😛
👩🏻💻 배우는 것을 즐기는 프론트엔드 개발자 입니다
부족한 블로그에 방문해 주셔서 감사합니다 🙇🏻♀️
in the process of becoming the best version of myself