
자바스크립트를 사용하면서 헷갈렸던 this 에 대해 정리해보려고 한다.
this자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-reference variable)이다.
형식적인 정의라고 할 수 있다. 실전에서 어떻게 사용이 되는지를 꼼꼼히 살펴봐야한다.
this는 일반 함수에서와 화살표 함수에서의 쓰임이 달라진다.
(함수를 호출하는 방법에 의해 this 의 값이 결정된다.)
this 는 호출 위치에서 정의한다.this 는 자신이 선언된(렉시컬) 범위에서 정의한다.✋ 여기서 렉시컬이란? 함수가 동작할 수 있는 유효한 범위를 뜻한다.
this 의 쓰임웹 브라우저에서는 window 객체가 전역 객체이므로, 이 때 this 는 window 가 되는 것이다.
(잘 사용해본 적은 없다.)
console.log(this === window); // true
a = 37;
console.log(window.a); // 37
this.b = "MDN";
console.log(window.b) // "MDN"
console.log(b) // "MDN"
this일반 함수의 this이므로, 호출 위치인 user 객체 데이터에서 getFullName의 값을 도출하게 된다.
const user = {
firstName: 'UDADA',
lastName: 'Park',
age: 85,
getFullName: function () {
return `${this.firstName} ${this.lastName}`
}
}
console.log(user.getFullName())
// Expected output: "UDADA Park"
꿀팁🌟
일반 함수를 사용할 때는 function 키워드를 생략해도 같은 결과가 나온다.
const user = {
firstName: 'UDADA',
lastName: 'Park',
age: 85,
getFullName() {
return `${this.firstName} ${this.lastName}`
}
}
this화살표 함수에서의 this 는 user 함수에 자신(this)이 선언된 범위인 user 함수에서의 값을 도출하게 된다.
function user() {
this.firstName = 'YuJeong'
this.lastName = 'Park'
return {
firstName: 'Neo',
lastName: 'Anderson',
age: 45,
getFullName: () => {
return `${this.firstName} ${this.lastName}`
}
}
}
const u = user()
console.log(u.getFullName())
// Expected output: YuJeong Park
❗️
this는 어떤 위치에 있느냐, 어디에서 호출하느냐, 어떤 함수에 있느냐에 따라 참조 값이 달라지는 특성이 있다. 그래서 사용할 때 주의해야 한다❗️
call()this 의 값을 다른 부분에서 사용하려면 call() 이나 apply() 메소드를 이용해야한다.
Function.call() 은 영어 그대로 호출한다 의 의미가 있는데, 주어진 this 값과 각각 전달된 인수와 함께 함수를 호출한다.
func.call(thisArg[, arg1[, arg2[, ...]]])
💡 이 함수 구문은 뒤에 다룰
apply()와 거의 동일하지만,call()은 인수 목록을, 반면에apply()는 인수 배열 하나를 받는다는 점이 중요한 차이점이다.
call() 은 이미 할당되어있는 다른 객체의 함수/메소드를 호출하는 해당 객체에 재할당할 때 주로 사용된다.
function Product(name, price) {
this.name = name;
this.price = price;
if (price < 0) {
throw RangeError('Cannot create product ' +
this.name + ' with a negative price');
}
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
console.log(cheese.name) // feta
console.log(cheese.price) // 5
console.log(cheese.category) // food
console.log(fun.name) // robot
console.log(fun.price) // 40
console.log(fun.category) // toy
👆 예시 코드에서 Product 함수를 호출하여 Food 와 Toy로 재할당한 것을 확인할 수 있다.
apply()func.apply(thisArg, [argsArray])
call() 과 비슷한 역할인 함수를 호출하는 메소드이지만, 함수를 호출하면서 인수를 배열 형태로 전달한다는 차이점이 있다.
👇 예시 코드에서처럼 기존 배열에 새로운 요소를 추가하고 싶을 때 유용하게 사용할 수 있다.
var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.log(array);
// Expected output: ["a", "b", 0, 1, 2]
🙌 push()
배열의 끝에 하나 이상의 요소를 추가하고, 배열의 새로운 길이 반환
bind()bind() 는 JavaScript 함수에 새로운 this 값과 초기 인수를 설정하여 새로운 함수를 반환하는 메소드이다.
이를 통해 함수의 this 값을 영구적으로 설정하고, 필요한 경우 인수를 미리 지정할 수 있다.
bind()는 호출되는 함수를 변경하지 않고 새로운 함수를 반환한다.
func.bind(thisArg[, arg1[, arg2[, ...]]])
반환된 함수는 원래 함수와 동일한 본문을 가지지만, bind() 메소드를 사용하여 설정한 this 값과 초기 인수를 가지게 된다.
const person = {
name: "John",
greet: function(message) {
console.log(`${message}, ${this.name}!`);
}
};
const greetFunc = person.greet.bind(person, "Hello");
greetFunc();
// Expected output: "Hello, John!"
👉 bind() 메소드는 person.greet 함수를 호출할 때 person 객체를 this 값으로 설정하고, 초기 인수로 "Hello"를 전달하는 새로운 함수인 greetFunc를 반환한다.
이후에 greetFunc() 를 호출하면 "Hello, John!"이 출력될 것이다 🖥️
bind() 는 함수를 미리 구성할 수 있어서, 나중에 필요한 시점에 함수를 호출할 때 추가 인수를 전달하지 않아도 된다. 이는 이벤트 처리할 때나 타이머와 함께 사용할 때 유용하다.
또한, this 값을 영구적으로 설정할 수 있으므로 객체의 메소드를 이벤트 핸들러로 사용할 때 유용하게 적용할 수 있다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/call
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind