this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수 (self-referencing variable)이다. this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
22.2 함수 호출 방식과 this 바인딩
this 바인딩은 함수 호출 방식에 의해 동적으로 결정됨
22.2.1 일반 함수 호출
기본적으로 this에는 전역 객체에 바인딩됨
일반 함수로 호출된 모든 함수 (중첩 함수, 콜백 함수 포함) 내부의 this에는 전역 객체 바인딩
// var 키워드로 선언한 전역 변수 value는 전역 객체의 프로퍼티.// const 키워드로 선언 시 전역 객체의 프로퍼티가 아님var value =1;const obj ={
value:100,foo(){console.log("foo's this: ",this);// {value: 100, foo: ƒ}// 1️⃣ 메서드 내에서 정의한 중첩 함수functionbar(){console.log("bar's this: ",this);// window 1console.log("bar's this.value: ",this.value);// 1}// 2️⃣ 콜백 함수 내부의 this에는 전역 객체 바인딩setTimeout(function(){console.log("callback's this: ",this);// windowconsole.log("callback's this.value: ",this.value);// 1},100);},};
객체 메서드 내부의 중첩 함수, 콜백 함수의 this 바인딩을 메서드의 this 바인딩과 일치시키는 방법
var value =1;const obj ={
value:100,execAssignment(){// 1️⃣ this 바인딩(obj)을 변수 that에 할당한다.const that =this;// 콜백 함수 내부에서 this 대신 that을 참조한다.setTimeout(function(){console.log(that.value);// 100},100);},execBind(){// 2️⃣ 콜백 함수에 명시적으로 this를 바인딩한다.setTimeout(function(){console.log(this.value);// 100}.bind(this),100,);},exexArrow(){// 3️⃣ 화살표 함수 내부의 this는 상위 스코프의 this를 가리킨다.setTimeout(()=>console.log(this.value),100);// 100},};
const person ={
name:'Son',getName(){// 메서드 내부의 this는 메서드를 호출한 객체에 바인딩됨returnthis.name;},};console.log(person.getName());// Son (메서드 getName을 호출한 객체는 person)const anotherPerson ={name:'Lee'};
anotherPerson.getName= person.getName;console.log(anotherPerson.getName());// Lee (getName 메서드를 호출한 객체는 anotherPerson)const getName = person.getName;console.log(getName());// '' (getName 메서드를 일반 함수로 호출)/**
* 일반 함수로 호출된 getName 함수 내부의 this.name은 브라우저 환경에서 window.name과 같음
* 브라우저 환경에서 window.name은 브라우저 창의 이름을 나타내는 빌트인 프로퍼티이며 기본값은 ''
* Node.js 환경에서 this.name은 undefined
*/
프로토타입 메서드 내부에서 사용된 this도 일반 메서드와 마찬가지로 해당 메서드를 호출한 객체에 바인딩됨
functionPerson(name){this.name= name;}Person.prototype.getName=function(){returnthis.name;};const me =newPerson('Son');// getName 메서드를 호출한 객체는 meconsole.log(me.getName());// ① SonPerson.prototype.name='Lee';// getName 메서드를 호출한 객체는 Person.prototypeconsole.log(Person.prototype.getName());// ② Lee
22.2.3 생성자 함수 호출
생성자 함수 내부의 this에는 생성자 함수가 생성할 인스턴스가 바인딩됨
// 생성자 함수functionCircle(radius){// 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다.this.radius= radius;this.getDiameter=function(){return2*this.radius;};}// 반지름이 5인 Circle 객체를 생성const circle1 =newCircle(5);// 반지름이 10인 Circle 객체를 생성const circle2 =newCircle(10);console.log(circle1.getDiameter());// 10console.log(circle2.getDiameter());// 20
22.2.4 Function.prototype.apply/call/bind
Function.prototype.apply/call/bind의 this 바인딩은 메서드 첫번째 인수로 전달한 객체
functiongetThisBinding(){returnthis;}const thisArg ={a:1};// bind 메서드는 함수를 호출하지는 않으므로 명시적으로 호출해야 한다.console.log(getThisBinding.bind(thisArg)());// {a: 1}const person ={
name:'Son',foo(callback){// bind 메서드로 callback 함수 내부의 this 바인딩을 전달setTimeout(callback.bind(this),100);},};
person.foo(function(){console.log(`Hi! my name is ${this.name}.`);// Hi! my name is Son.});
apply, call 메서드와 달리 함수를 호출하지 않음
첫번째 인수로 전달한 값으로 this 바인딩이 교체된 함수를 새롭게 생성하여 반환
22.1 this 키워드
this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수 (self-referencing variable)이다.this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.22.2 함수 호출 방식과 this 바인딩
this바인딩은 함수 호출 방식에 의해 동적으로 결정됨22.2.1 일반 함수 호출
기본적으로
this에는 전역 객체에 바인딩됨일반 함수로 호출된 모든 함수 (중첩 함수, 콜백 함수 포함) 내부의
this에는 전역 객체 바인딩객체 메서드 내부의 중첩 함수, 콜백 함수의
this바인딩을 메서드의this바인딩과 일치시키는 방법this할당하여 중첩 함수, 콜백 함수에서 사용Function.prototype.apply/call/bind메서드로this를 명시적으로 바인딩this바인딩 일치 (화살표 함수 내부의this는 상위 스코프의this를 가리킴)strict mode가 적용된 일반 함수 내부의
this는undefined바인딩22.2.2 메서드 호출
메서드 내부의 this에는 메서드를 호출한 객체가 바인딩됨
메서드 내부의 this는 메서드를 소유한 객체가 아닌 메서드를 호출한 객체에 바인딩됨
프로토타입 메서드 내부에서 사용된
this도 일반 메서드와 마찬가지로 해당 메서드를 호출한 객체에 바인딩됨22.2.3 생성자 함수 호출
생성자 함수 내부의
this에는 생성자 함수가 생성할 인스턴스가 바인딩됨22.2.4 Function.prototype.apply/call/bind
Function.prototype.apply/call/bind의this바인딩은 메서드 첫번째 인수로 전달한 객체apply,call메서드apply와call메서드의 본질적인 기능은 함수를 호출하는 것bind메서드apply,call메서드와 달리 함수를 호출하지 않음첫번째 인수로 전달한 값으로
this바인딩이 교체된 함수를 새롭게 생성하여 반환