인터뷰 질문: 자바스크립트에서 `this`가 어떻게 작동하는지 설명하십시오[3분 이내].

JavaScript에서 this은 함수가 실행되는 실행 컨텍스트의 속성입니다.
this이 어떻게 평가되는지에 대한 설명은 매우 정교하며 this MDN article에서 사례별로 포괄적으로 다룹니다.

함수의 this 값은 함수가 정의된 방식이 아니라 함수가 호출 사이트에서 호출되는 방식에 따라 결정됩니다. 엄격 모드가 활성화되었는지 여부, 함수가 정의되고 독립 실행형으로 호출되었는지 여부 객체의 메서드로 함수를 호출하는지 또는 객체 메서드의 참조를 추출한 다음 다른 곳에서 호출하는지 등.

실행 컨텍스트



함수의 실행 컨텍스트는 런타임에 함수가 실행되는 환경입니다. 여기에는 변수 범위, 함수 인수 및 this 개체의 값이 포함됩니다.

이것



사용하려는 개체의 속성에 따라 작동하는 함수가 필요한 경우 this이 해당 개체여야 합니다. 즉, 우리 함수의 대상 개체는 런타임 시 실행 컨텍스트에서 사용할 수 있어야 하므로 this 으로 액세스할 수 있습니다.

일반 모드에서 this은 항상 개체입니다. undefinednull 값은 전역 객체(브라우저의 window 객체)에 오토박스 처리됩니다. 그러나 엄격 모드에서는 undefined 또는 null 일 수 있습니다. 엄격 모드에서는 this 의 오토박싱이 없기 때문입니다.

function testThis() {
  return this;
};
console.log(testThis()); // [object Window]

function testThisInStrictMode() {
  'use strict'
  return this;
};
console.log(testThis()); // undefined


개체에서


this 을 사용하는 메서드가 있는 개체가 있고 개체에 대한 메서드를 호출하면 개체가 자동으로 메서드의 this 에 할당됩니다.

const person = {
  name: 'Abd',
  age: 42,
  sayHi: function() {
    return `Hi, this is ${this.name}`;
  },
};

console.log(person.sayHi()); // "Hi, this is Abd"


클래스뿐만 아니라 생성자 함수를 사용하여 생성된 사용자 지정 개체의 인스턴스에도 동일하게 적용됩니다.

// constructor function example
function Person() {
  this.name = 'Abd';
  this.age = 42;
  this.sayHi = function() {
    return `Hi, this is ${this.name}`;
  };
};
const person = new Person();
console.log(person.sayHi()); // "Hi, this is Abd"

// class example
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  };

  sayHi() {
    return `Hi, this is ${this.name}`;
  };
};

const person = new Person('Abd', 42);
console.log(person.sayHi()); // "Hi, this is Abd"



함수 참조



아마도 JavaScript에서 this에 대해 가장 강조할 수 있는 사례는 개체에서 메서드 참조를 추출한 다음 다른 곳에서 호출하려는 경우에 발생합니다.

예를 들어, sayHi() 개체의 person 메서드(위의 예제 중 하나에서)를 변수에 저장한 다음 나중에 호출하면 메서드가 작동하도록 설정된 개체가 없습니다. 참조된 함수에서 개체를 효과적으로 분리하므로 런타임 시 이 함수의 this은 일반 모드 또는 엄격 모드에 따라 전역 개체 또는 undefined이 됩니다.

`use strict`
const sayHiAbd = person.sayHi; // Note that person.sayHi is NOT being invoked here
console.log(sayHiAbd()); // Error: Cannot read property 'name' of undefined



이 시나리오에서 sayHiAbd()은 다음과 같이 정의된 독립 실행형 함수와 같습니다.

function sayHiAbd() {
  return `Hi, this is ${this.name}`;
};


이러한 경우 호출 사이트에서 .call() 개체를 명시적으로 설정하려면 .apply() 또는 this을 사용하여 함수를 호출해야 합니다.

console.log(sayHiAbd.call({name: 'Abd', age: 42})); // "Hi, this is Abd"


영구적으로 바인딩



개체를 함수에 영구적으로 바인딩하려면 개체를 새 함수에 연결하는 .bind() 을 사용하여 새 함수를 만들어야 합니다.

const alwaysSayHiAbd = sayHiAbd.bind({name: 'Abd', age: 42});
console.log(alwaysSayHiAbd()); // "Hi, this is Abd"


화살표 구문



화살표 구문은 함수 정의의 둘러싸는 어휘 컨텍스트를 실행 컨텍스트에 영구적으로 바인딩합니다. 따라서 호출 사이트 컨텍스트는 화살표 함수와 간섭하지 않습니다.

위의 객체 리터럴 person 예제에서 인사말 문자열을 반환하는 화살표 함수를 반환하도록 sayHi() 함수를 수정하면 반환된(화살표) 함수의 thisperson 객체 자체인 주변 어휘 컨텍스트에 바인딩됩니다. 그것에 대한 참조를 저장하고 호출하면 항상 this 에서 person 을 가리킵니다.

const person = {
  name: 'Abd',
  age: 42,
  sayHi: function() {
    return () => `Hi, this is ${this.name}`;
  },
};
const sayHiAbd = person.sayHi();
console.log(sayHiAbd()); // "Hi, this is Abd"




참조
  • this
  • ECMAScript standard - ResolveThisBinding
  • 좋은 웹페이지 즐겨찾기