this
는 자신이 속한 객체나 자신이 생성할 인스턴스를 가리키는 참조 변수this
에 바인딩할 객체가 동적으로 결정된다this
는 Global Object
를 가리킨다Global Object
는 window
객체, 서버 상에서 Global Object
는 global
객체function func() {
console.log(this);
}
func(); // window
func()
방식으로 함수 호출하는 방식이 일반적인 함수 호출 방식const name = "jhj";
function func() {
console.log(this.name);
}
func(); // jhj
name
은 Global Object
인 window의 속성으로 추가된다 → window.name
생성console.log(this.name) == console.log(window.name)
'use strict';
const name = "jhj";
function func() {
console.log(this.name);
}
func(); // error
strict mode
에서 this는 window를 가리키지 않는다const obj1 = {
name: "jhj",
getName: function() {
console.log(this.name);
}
}
const obj2 = {
name: "krkorklo"
}
obj2.getName = obj1.getName;
obj1.getName(); // jhj
obj2.getName(); // krkorklo
new
연산자를 붙여 호출하면 생성자 함수로 동작this
바인딩this
를 사용해 property 생성function Person(name) {
this.name = name;
}
const person = new Person("jhj");
console.log(person); // jhj
Person.prototype
을 프로토타입 객체로 가지는 객체가 생성new 연산자를 붙이지 않는 경우
function Person(name) {
this.name = name;
}
const person = Person("jhj");
console.log(person); // undefined
console.log(window.name); // jhj
new
없이 생성자 함수를 호출하면 this를 암묵적으로 반환하지 않아 undefined가 반환new
없이 생성자 함수를 호출한 경우 Persom 내부의 this는 전역 객체를 가리키게 되어 전역 변수에 바인딩this
에 바인딩될 객체는 함수 호출 패턴에 따라 JavaScript 엔진이 동적으로 바인딩apply
, call
, bind
사용this
를 특정 객체에 바인딩const Person = function (name) {
this.name = name;
}
const per = {};
Person.apply(per, ['jhj']);
console.log(per); // { name : 'jhj' }
Person
함수의 this
가 per 객체가 된다this(per)
에 name property가 없으므로 name이 동적으로 추가되고 값이 할당apply
와 기능은 같지만 배열 형태로 arguments를 넘기는 것이 아니라 하나씩 인자로 전달Person.call(per, 'jhj');
call
, apply
와 달리 함수를 실행하는 것이 아니라 연결만 하는 것const Person = function (name) {
this.name = name;
console.log(this);
};
const per = { age: 23 };
const newPer = Person.bind(per, "jhj");
newPer();
function
키워드 없이 =>
화살표 표시로 함수를 선언const func = () => console.log("function");
this
가 존재하지 않기 때문에 상위 환경의 this
를 참조한다this
가 동적으로 바인딩되지만 화살표 함수에서는 선언될 시점의 상위 스코프가 this
로 정적 바인딩function Person(name) {
this.name = name;
}
Person.prototype.console = function (arr) {
// this는 상위 스코프인 Person 메소드 내의 this를 가리킨다
return arr.map(x => `${this.name} ${x}`);
};
const person = new Person('krkorklo');
console.log(person.console(['hi', 'hello']));
apply
, call
, bind
를 사용해 this를 변경할 수 없다const person = {
name: "jhj",
console: () => console.log(`hi ${this.name}`)
}
person.console(); // hi undefined
this
가 상위 컨텍스트의 전역 객체(window
)를 가리키게 된다const person = {
name: "jhj"
}
Object.prototype.getName = () => console.log(`hi ${this.name}`);
person.getName(); // hi undefined
this
가 상위 컨텍스트의 전역 객체를 가리키게 되므로 일반 함수를 사용해야한다prototype
property를 가져 prototype
property가 가리키는 프로토타입 객체의 constructor
를 사용해서 객체 생성prototype
property를 가지지 않으므로 화살표함수를 사용하면 안된다const Person = () => {};
const person = new Person(); // Person is not a constructor
window
)를 가리킨다let button = document.getElementById('button');
button.addEventListener('click', () => {
console.log(this === window); // true
});
button.addEventListener('click', function() {
console.log(this === button); // true
});
참고자료
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
https://poiemaweb.com/js-this
https://poiemaweb.com/es6-arrow-function