JavaScript this 정리
JavaScript에서 this
키워드는 흔히 객체지향적으로 자바스크립트를 작성할 때 종종 사용되곤 한다. 하지만 학부생 수준에서 배우게 되는 다른 객체지향언어(C++ / Java)와는 여러가지 상이한 점이 존재한다.
다음은 평범한 this
의 용례다.
function Person(name, age) { this.name = name; this.age = age; } var hyunseob = new Person('이현섭', 27); console.log(hyunseob.name); // 이현섭 console.log(hyunseob.age); // 27 |
생성자(constructor)로서 사용하게 되면 다른 객체지향 언어와 비슷한 방식. 즉, 생성된 객체의 멤버변수를 참조하게 된다. 이것은 prototype
을 사용해서 정의한 객체의 메소드에서도 동일하다.
// 위 코드에 이어서 Person.prototype.isYoung = function() { return this.age < 25; } console.log(hyunseob.isYoung()); // false |
하지만 this
키워드는 기본적으로 전역객체(브라우저에서는 window
와 같다.)이므로 굳이 위와 같이 객체 메소드 내부에서 호출하지 않아도 사용할 수 있다.
console.log(this.hyunseob.isYoung()); // false console.log(window === this) // true |
this
를 생성자 혹은 객체의 메소드에서 사용하지 않는 경우 this
는 전역객체가 된다.
var seungmin = Person('이승민', 28); console.log(seungmin); // undefined console.log(name); // 이승민 console.log(age); // 28 |
위에서는 Person
함수를 new
키워드 없이 사용.. 즉, 생성자로 사용하지 않았기 때문에 this
가 전역객체가 되었고, 덩달아 name
과 age
는 전역변수가 된 것이다. 더구나 Person
함수는 리턴하는 값이 없기 때문에 seungmin
이라는 변수는 값이 초기화 되지 않았다. 미안해요 승민이형
특히, strict mode를 사용해서 함수를 정의하는 경우에는 다음과 같이 this
는 undefined
값이 된다.
function returnThis() { return this; } function returnThisStrict() { 'use strict'; return this; } console.log(returnThis() === this); // true console.log(returnThisStrict() === this); // false console.log(returnThisStrict()); // undefined |
하지만 strict mode로 정의한 함수라도 특정 객체의 메소드로 호출된다면 this
는 호출한 객체를 참조하게 된다.
console.log(window.returnThisStrict() === window); // true
|
또한, 다음과 같이 apply
를 사용해서 내가 원하는 값을 this
로 던져줄 수 있다.
var jaehoon = {}; Person.apply(jaehoon, ['석재훈', 28]); console.log(jaehoon.name); // 석재훈 console.log(jaehoon.age); // 28 |
이것은 call
을 사용해도 똑같이 구현할 수 있다.
var hosuk = {}; Person.call(hosuk, '신호석', 24); console.log(hosuk.name); // 신호석 console.log(hosuk.age); // 24 |
call
과 apply
는 this
로 넘겨지는 값이 객체가 아닐 때 자동으로 객체로 변환하므로 조심해야 한다. 또한 만약 this
로 null
혹은 undefined
같은 값을 넘기는 경우 this
는 전역객체를 참조한다.
ES5에서는 this
값을 넘기기 위해서 bind
를 사용할 수도 있다. 이것은 ES6-cheatsheet에서 언급한 예에서 처럼 중첩된 함수 내에서 this
의 컨텍스트를 보존하는 용도로 종종 사용된다.
var heeduk = {}; Person.bind(heeduk)('이희덕', 30); console.log(heeduk.name); // 이희덕 console.log(heeduk.age); // 30 |