JavaScript에서의 this

유정·2023년 7월 11일
0
post-thumbnail

자바스크립트를 사용하면서 헷갈렸던 this 에 대해 정리해보려고 한다.

this

자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-reference variable)이다.

형식적인 정의라고 할 수 있다. 실전에서 어떻게 사용이 되는지를 꼼꼼히 살펴봐야한다.

this일반 함수에서와 화살표 함수에서의 쓰임이 달라진다.

(함수를 호출하는 방법에 의해 this 의 값이 결정된다.)

  • 일반 함수의 this호출 위치에서 정의한다.
  • 화살표 함수의 this자신이 선언된(렉시컬) 범위에서 정의한다.

✋ 여기서 렉시컬이란? 함수가 동작할 수 있는 유효한 범위를 뜻한다.


this 의 쓰임

웹 브라우저에서는 window 객체가 전역 객체이므로, 이 때 thiswindow 가 되는 것이다.
(잘 사용해본 적은 없다.)

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

화살표 함수에서의 thisuser 함수에 자신(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 함수를 호출하여 FoodToy로 재할당한 것을 확인할 수 있다.

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

profile
오늘은 모르더라도 내일은 아는 사람

0개의 댓글