this는 본인이 속해있는 객체를 참고합니다. 이 말인 즉슨, 어디서 어떻게 사용되느냐에 따라서 다른 값을 가진다는 겁니다. (어디서 호출했는지가 중요!)
아무 것도 속하지 않은 범위에서의 this는 전역 객체를 참고합니다.웹 브라우저에서는 window가 전역 객체입니다.
name = "Chungsik"
console.log(this) // Window;
console.log(name) // Chungsik
console.log(this.name) // Chungsik
console.log(window.name) // Chungsik
함수를 어떤 객체의 메소드로 호출했을 때, this의 값은 그 객체를 사용합니다.
let user = {
name: "Chungsik",
greetUser: function() {
console.log(`Hello ${this.name}`)
}
};
user.greetUser() = Hello Chungsik
let user = {
name: "Chungsik",
computer: {
greetUser: function() {
console.log(`Hello ${this.name}`) // this가 undefined
}
}
};
user.computer.greetUser() = Hello undefined // use call, apply, bind... to solve this problem
함수 내부에서는 함수를 호출한 방법에 따라서 달라집니다.
function fnc() {
return this;
}
fnc() // Window;
function fnc() {
"use strict";
return this;
}
fnc() // undefined;
window.fnc() // window;
let user = {
name: "Chungsik",
computer: {
greetUser: function (team, partner) {
console.log(`Hello ${this.name}, your team name is ${team} with ${partner}`)
}
}
};
// Call & Apply need to invoke immediately
user.computer.greetUser.call(user, "Alpha", "Eunwoo")
// Hello Chungsik, your team name is Alpha with Eunwoo
// call은 단일 인자를 전달합니다.
user.computer.greetUser.apply(user, ["Bravo", "Yeri"])
// Hello Chungsik, your team name is Bravo with Yeri
// apply는 배열 인자를 전달합니다.
let user = {
name: "Chungsik",
computer: {
greetUser: function (team, partner) {
console.log(`Hello ${this.name}, your team is ${team} with ${partner}`)
}
}
};
// Bind returns a copy of the function which can be invoked later
let greet = user.computer.greetUser.bind(user)
greet("Charlie", "Jihoon") // Hello Chungsik, your team name is Charlie with Jihoon
arrow function은 자신을 포함하는 외부 scope에서 this를 계승 받습니다.
let user = {
name: "Chungsik",
computer: {
greetUser: (team, partner) => {
console.log(`Hello ${this.name}, your team is ${team} with ${partner}`)
}
}
};
user.computer.greetUser("Delta", "Doori") // Hello , your team is Delta with Doori
// 위와 같이 하면 객체의 this는 바인딩하지 않고 전역 객체가 바인딩 됩니다.
// 즉, 객체의 메소드를 정의할 때는 사용하면 안됩니다.
함수 내부에서 this는 window 객체입니다.
// arrow function 적용 전
function Greeting(greet) {
this.greet = greet;
}
Greeting.prototype.nameArray = function (arr) {
console.log(this.greet); // 여기서 this.greet는 Hello 입니다.
return arr.map(function (x) {
return this.greet + ' ' + x; // 하지만 여기서 this.greet는 undefined 입니다.
});
};
var gre = new Greeting("Hello");
console.log(gre.nameArray(["Chungsik", "Yeri"]));
// ["undefined Chungsik","undefined Yeri"]
함수 내부더라도 arrow function을 쓰면 this 상위 context(함수가 속해있는 객체)를 가리킵니다.
// arrow function 적용 후
function Greeting(greet) {
this.greet = greet;
}
Greeting.prototype.nameArray = function (arr) {
return arr.map(x => `${this.greet} ${x}`); // 여기서 this.greet는 Hello 입니다.
};
const gre = new Greeting("Hello");
console.log(gre.nameArray(["Chungsik", "Yeri"]));
// ["Hello Chungsik","Hello Yeri"]
와우!