[JavaScript] This 개념 다지기

문정민·2023년 11월 29일

Javascript

목록 보기
6/6

업로드중..

📝This

자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수이다. 일반함수에서 this를 사용하는 것은 그 기능과 목적에 부합하지 않을 수 있다. 그럼에도 불구하고 this는 코드의 어디에서는 참조 가능하다.

✅ this에 바인딩될 값는 함수가 어떻게 호출되었는지에 따라 동적으로 결정된다. 다시 말해, 누가 함수를 호출했는가에 따라서 this가 가리키는 값이 달라진다.

📝함수 호출 방식과 this

1. 메서드 호출

const city = {
  name: 'Seoul',
  getName: function () {
    console.log(`여기는 ${this.name}입니다.`)
  }
}

city.getName(); // 여기는 Seoul입니다.
  • this를 호출한 객체는 city이므로 this는 city를 가리킨다.
const city2 = {
  name: 'Busan',
  getName: city.getName
}

city2.getName(); // 여기는 Busan입니다.
  • 마찬가지로, this를 호출한 객체가 city2이므로 this는 city2를 가리킨다.

2. 일반 함수 호출

const city = {
  name: 'Seoul',
  getName: function () {
    console.log(`여기는 ${this.name}입니다.`)
  }
}

const getCityName = city.getName;
getCityName(); // 여기는 입니다. 
			  // this를 출력해보면 window객체가 나온다.
  • city.getName을 변수에 할당하고 함수를 호출하면, this는 전역 객체인 윈도우 객체를 가리킨다.
  • getCityName를 호출한 것이 윈도우 객체라고 이해하면 쉽다.

3. 생성자 함수 호출

function City(name) {
  this.name = name,
    this.getName = function () {
    console.log(`여기는 ${this.name}입니다.`)
  }
}

const city1 = new City('Incheon');
city1.getName(); // 여기는 Incheon입니다
  • 생성자 함수 내부의 this는 생성할 인스턴스를 가리킨다.

📝 this를 고정할 수 없을까?

원하는 객체에 this를 바인딩하기 위해서는 call, apply, bind 메서드를 사용할 수 있다.

💡 Function.prototype.call()

func.call(thisArg[, arg1[, arg2[, ...]]])

  • 주어진 this 값 및 각각 전달된 인수와 함께 홈수를 호출한다.
  • 매개변수로 인수의 목록을 받는다.
  • 즉시 함수를 호출한다.

일반 객체의 경우

const city = {
  name: 'Seoul',
  getLocation: function (year, country) {
    console.log(`여기는 ${year}${country}${this.name}입니다.`);
  }
}

const city2 = {
  name: 'New York'
}

city.getLocation.call(city2, '2358', 'USA'); // 여기는 2358년 USA의 New York입니다.

생성자 함수의 경우

function City(name, country, year) {
  this.name = name;
  this.country = country;
  this.year = year;
  this.getLocation = function () {
    console.log(`여기는 ${this.year}${this.country}${this.name}입니다.`);
  }
}

const city3 = {};
City.call(city3, 'London', 'UK', 3100);
city3.getLocation(); //여기는 3100년 UK의 London입니다.

💡Function.prototype.apply()

func.apply(thisArg, [argsArray]);

  • 주어진 this값과 배열(유사 배열 객체 포함)로 제공되는 arguments로 함수를 호출한다.
  • 매개변수로 인수들의 단일 배열을 받는다.
  • 즉시 함수를 호출한다.

일반 객체의 경우

const city = {
  name: 'Seoul',
  getLocation: function (year, country) {
    console.log(`여기는 ${year}${country}${this.name}입니다.`);
  }
}

const city2 = {
  name: 'Paris'
}

city.getLocation.apply(city2, [2024, 'France']); // 여기는 2024년 France의 Paris입니다.

생성자 함수의 경우

function City(name, country, year) {
  this.name = name;
  this.country = country;
  this.year = year;
  this.getLocation = function () {
    console.log(`여기는 ${this.year}${this.country}${this.name}입니다.`);
  }
}

const city4 = {};
City.apply(city4, ['Bangkok', 'Thailand', 1024]);
city4.getLocation(); //여기는 1024년 Thailand의 Bangkok입니다.

💡 Function.prototype.bind()

func.bind(thisArg[, arg1[, arg2[, ...]]])

  • 첫 번째 인자의 value로는 this 키워드를 설정하고, 이어지는 인자들은 바인드된 함수의 인수에 제공된다.
  • 메서드가 호출되면 새로운 함수를 반환한다. 즉시 함수를 호출하지 않는다.

일반 객체의 경우

const city = {
  name: 'Seoul',
  getLocation: function (year, country) {
    console.log(`여기는 ${year}${country}${this.name}입니다.`);
  }
}

const city5 = {
  name: 'Rome'
}

const getLocationInfo = city.getLocation.bind(city5, 500, 'Italy');
getLocationInfo();

생성자 함수의 경우

  • bind는 생성자 함수에서 일반적으로 자주 사용되지 않는다는 gpt의 답변으로 예제는 패스

📝화살표 함수와 this

✅ 화살표 함수에서의 this는 상위 스코프의 this와 동일한 값을 가진다.

const city = {
  name: 'Seoul',
  getLocation: () => {
    console.log(`여기는 ${this.name}입니다.`)
  }
}
city.getLocation(); // 여기는 입니다. 
				   // this는 윈도우 객체를 가리킨다.
  • getLocation이라는 화살표 함수는 city 내에 정의되어있다. city의 상위 스코프는 전역 스코프이므로 this가 window를 가리킨다.

❓화살표 함수는 왜 상위 스코프의 this값을 상속할까?

<ChatGPT 답변>
1. 콜백 함수에서의 this 문제 해결
: 전통적인 함수에서 this는 함수가 호출되는 방식에 따라 동적으로 결정됩니다. 이는 콜백 함수나 클로저 내에서 종종 문제를 일으키곤 했습니다. 예를 들어, 객체의 메소드 내부에서 setTimeout과 같은 비동기 함수를 사용할 때, 콜백 함수 내부의 this가 원래 객체를 가리키기를 기대하지만, 실제로는 전역 객체나 undefined를 가리키는 경우가 흔했습니다. 화살표 함수를 사용하면 이러한 문제를 해결할 수 있습니다.

2. 코드의 간결성과 가독성 향상
: 렉시컬 this 덕분에 that = this 또는 self = this와 같은 패턴을 사용하지 않아도 됩니다. 이러한 패턴은 과거에 this를 다른 스코프에 "고정"시키기 위해 자주 사용되었지만, 코드를 더 복잡하게 만드는 경향이 있었습니다.

0개의 댓글