함수가 어떻게 호출되었는지 함수가 호출되는 방식에 따라 this
바인딩이 동적으로 결정된다.
즉, this
값은 런타임에 결정된다.
this
는 메서드를 호출한 객체를 참조합니다.
메서드가 어디에 정의되어 있는지 상관하지 않는다.
항상 메서드가 정의된 객체를 참조하는 bound this
개념과는 다른 자바스크립트의 특징이다.
let user = {
name: "John",
age: 30,
sayHi() {
// 'this'는 '현재 객체'를 나타냅니다.
console.log(this.name);
}
};
user.sayHi(); // John
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
console.log( this.name );
}
// 별개의 객체에서 동일한 함수를 사용함
user.f = sayHi;
admin.f = sayHi;
// 'this'는 '점(.) 앞의' 객체를 참조하기 때문에
// this 값이 달라짐
user.f(); // John (this == user)
admin.f(); // Admin (this == admin)
admin['f'](); // Admin (점과 대괄호는 동일하게 동작함)
function sayHi() {
console.log(this);
}
sayHi(); // undefined
함수를 일반 함수로 호출 시 함수 내부의 this
는 전역객체를 가리킨다.
엄격 모드에서는 undefiend
가 할당된다.
엄격 모드가 아니라면 Node.js에서는 전역객체 global
이, 브라우저에서는 전역객체 window
가 바인딩된다.
최근에는 전역객체를 globalThis
로 표준화하였기 globalThis
전역객체가 바인딩된다.
콜백 함수가 일반 함수로 호출된다면 콜백 함수 내부의 this
도 전역 객체가 바인딩된다.
생성자 함수로 호출 시 함수 내부의 this
는 생성자 함수가 생성할 인스턴스가 바인딩된다.
function User(name) {
// this = {}; (빈 객체가 암묵적으로 만들어지고 this에 할당)
// 새로운 프로퍼티를 this에 추가함
this.name = name;
this.isAdmin = false;
// return this; (this가 암묵적으로 반환됨)
}
화살표 함수는 고유의 this
값을 가지지 않는다.
화살표 함수는 일반 함수로 호출되든 메서드로 호출되든 자체 this
바인딩을 하지 않는다.
화살표 함수 내부에서 this, arguments, super, new.target
을 참조하면
스코프 체인을 통해 상위 스코프의 this, arguments, super, new.target
를 참조한다.
let user = {
firstName: "민교",
sayHi() {
let arrow = () => console.log(this.firstName);
arrow();
}
};
user.sayHi(); // 민교
내부 함수의 this
는 외부 함수(여기서는 메서드 sayHi)의 this
를 참조한다.
apply, call, bind
메서드는 Function.prototype
의 메서드다.
따라서 이 메서드들은 모든 함수가 상속해 사용한다.
***apply, call, bind
메서드의 첫 번째 인수는 this
로 사용할 객체다.***
apply, call
메서드의 첫 번째 인수는 this
로 사용할 객체다.
function getThisBinding() {
return this;
}
const thisArg = {a:1};
console.log(getThisBinding()); // undefined;
console.log(getThisBinding.apply(thisArg)); // {a:1}
console.log(getThisBinding.call(thisArg)); // {a:1}
apply, call
메서드의 본질적인 기능은 함수를 호출하는 것이다. 즉, apply, call
메서드로 getThisBinding
함수를 호출하는 것이다.
apply, call
메서드의 두 번째 인수는 둘이 조금 다르다.
apply
메서드의 두 번째 인수는 호출할 함수의 인수를 배열로 전달한다.
call
메서드의 두 번째 인수는 호출할 함수의 인수를 목록으로(가변 인자) 전달한다.
function getThisBinding() {
console.log(arguments);
return this;
}
const thisArg = {a:1};
console.log(getThisBinding.apply(thisArg));
// Arguments(3) [1,2,3, callee: f, Symbol(Symbol.iterator): f]
// {a:1}
console.log(getThisBinding.call(thisArg));
// Arguments(3) [1,2,3, callee: f, Symbol(Symbol.iterator): f]
// {a:1}
bind
메서드는 첫 번째 인수로 전달한 값으로 this
바인딩 한 함수를 새롭게 생성해 반환한다.
function getThisBinding() {
return this;
}
const thisArg = {a:1};
console.log(getThisBinding.bind(thisArg)); // getThisBinding;
console.log(getThisBinding.bind(thisArg)()); // {a:1};