시대의 명작 코어 자바스크립트를 읽고 자바스크립트 마스터에 도전합니다... (this는 챕터 3이지만, 실행 컨텍스트가 어려워서 먼저 공부하기로!)
this
는 기본적으로 실행 컨텍스트가 생성될 때 함께 결정된다. 즉 함수를 호출할 때 결정된다. 함수를 어떤 방식으로 호출하느냐에 따라 값이 달라진다고 생각하면 된다.
전역 공간에서의 this
는 전역 객체를 가리킨다. 브라우저 환경에서 전역 객체는 window
, Node.js 환경에서는 global
이다.
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1
함수와 메서드 둘 다 미리 정의한 동작을 수행하는 코드 뭉치이지만, 함수는 그 자체로 독립적인 기능을 수행하는 반면에, 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행한다는 차이가 있다.
메서드는 그 자체로 메서드가 되는 것이 아니라 객체의 메서드로서 호출할 경우에만 메서드로 동작하고, 그렇지 않으면 함수로 동작한다. 함수로서 호출
과 메서드로서 호출
을 구분하는 방법은 함수 앞에 점(.
)이 있는지만 보면 된다. 점 표기법이든 대괄호 표기법이든 어떤 함수를 호출할 때 그 앞에 객체가 명시되어있는 경우는 메서드로 호출한 것, 그 외의 모든 경우는 함수로 호출한 것이다.
var obj = {
method: function (x) { console.log(this.x) }
};
obj.method(1); // { method: f } 1
obj['method'](2) // { method: f } 2
this
에는 호출한 주체에 대한 정보가 담긴다. 따라서 어떤 함수를 메서드로서 호출하는 경우 그 주체는 함수명(프로퍼티명) 앞의 객체이다.
함수로서 호출하는 것은 호출 주체를 명시하지 않고 실행한 것이기 때문에 주체의 정보를 알 수 없다. this
가 지정되지 않은 경우 전역 객체를 바라보게 된다.
this 바인딩에 관해서는 함수를 실행하는 당시의 주변 환경(메서드 내부인지 함수 내부인지 등)은 중요하지 않다. 오직 해당 함수를 호출할때 함수로서 호출되었는지, 메서드로서 호출되었는지가 중요하다.
var obj1 = {
outer: function () {
console.log(this);
var innerFunc = function () {
console.log(this);
}
innerFunc(); // this = Window(전역객체)
var obj2 = {
innerMethod: innerFunc
};
obj2.innerMethod(); // this = obj2
}
};
obj1.outer(); // this = obj1
자체적으로 내부 함수에 this를 상속할 방법은 없으나 이를 우회할 수는 있다. 바로 변수를 이용하는 방법.
var obj = {
outer: function () {
console.log(this); // { outer: f }
var innerFunc1 = function () {
console.log(this); // Window { ... }
}
innerFunc1();
var self = this;
var innerFunc2 = function () {
console.log(self);
};
innerFunc2();
}
};
obj1.outer();
self
라는 변수에 this
를 저장한 상태에서 호출한 innerFunc2
의 경우 self
에는 객체 obj
가 출력된다.
ES6에서는 함수 내부에서 this
가 전역객체를 바라보는 문제를 보완하고자 this
를 바인딩하지 않는 화살표 함수를 새로 도입했다. 화살표 함수는 실행 컨텍스트를 생성할때 this 바인딩 과정이 빠져서 상위 스코프의 this
를 그대로 사용할 수 있게 된다.
var obj = {
outer: function () {
console.log(this); // { outer: f }
var innerFunc = () => {
console.log(this); // { outer: f }
};
innerFunc();
}
};
obj.outer();
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a')
.addEventListener('click', function (e) {
console.log(this, e);
})
addEventListener
메서드는 콜백 함수를 호출할때 자신의 this
를 상속하도록 정의되어있다. 따라서 메서드의 점 앞부분이 this
가 되는 것이다.
콜백 함수에서 this
는 딱 정할 수 없다. 콜백함수의 제어권을 가지는 함수(메서드)가 this
를 결정하고, 정의되지 않은 경우 전역객체를 바라본다.
생성자 함수는 어떤 공통된 성질을 지닌 객체들을 생성하는데 사용되는 함수이다. 자바스크립트는 함수에 생성자로서의 역할을 함께 부여했다. new
명령어와 함께 함수를 호출하면 해당 함수가 생성자로서 동작한다. 이 경우 내부에서 this
는 곧 새로 만들 인스턴스 자신이 된다
var Cat = function (name, age) {
this.bark = '야옹';
this.name = name;
this.age = age;
};
var coco = new Cat('코코', 7);
var nabi = new Cat('나비', 12);
console.log(coco, nabe);
// Cat { bark: '야옹', name: '코코', age: 7 }
// Cat { bark: '야옹', name: '나비', age: 12 }
크.. 열심히 하구있네영 화이팅!