[자바스크립트 Deep Dive] 22. this

unhyif·2023년 3월 16일
0

22.1 this 키워드

자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수

  • JS 엔진에 의해 암묵적으로 생성되며, 어디서든 참조 가능함
  • 함수 호출 방식에 의해 동적으로 결정됨

22.2 함수 호출 방식과 this 바인딩

22.2.1 일반 함수 호출

strict mode 해제 시 전역 객체, 적용 시 undefined가 바인딩 됨

  • strict mode 해제 시 일반 함수 + 중첩 일반 함수
function foo() {
  console.log(this); // window

  function bar() {
    console.log(this); // window
  }
  bar();
}

foo();
  • strict mode 적용 시 일반 함수 + 중첩 일반 함수
'use strict';


function foo() {
  console.log(this); // undefined

  function bar() {
    console.log(this); // undefined
  }
  bar();
}

foo();
  • 메소드 + 메소드 내 중첩 일반 함수
const obj = {
  foo() {
    console.log(this); // {foo: ƒ}

    function bar() {
      console.log(this); // window
    }
    bar();
  },
};

obj.foo();
  • 메소드 + 메소드 내 콜백 일반 함수
const obj = {
  foo() {
    console.log(this); // {foo: ƒ}

    setTimeout(function () {
      console.log(this); // window
    }, 1000);
  },
};

obj.foo();

메소드 내 중첩 or 콜백 일반 함수의 this 바인딩을 메소드와 일치시키는 방법

  1. 메소드의 this를 지역 변수에 할당
const obj = {
  foo() {
    const that = this;

    setTimeout(function () {
      console.log(that); // {foo: ƒ}
    }, 1000);
  },
};

obj.foo();
  1. 타겟 함수에 bind 적용
const obj = {
  foo() {
    console.log(this); // {foo: ƒ}

    const bar = function () {
      console.log(this); // {foo: ƒ}
    }.bind(this);

    bar();
  },
};

obj.foo();
  1. 타겟 함수를 화살표 함수로 변경
const obj = {
  foo() {
    console.log(this); // {foo: ƒ}

    setTimeout(() => console.log(this), 1000); // {foo: ƒ}
  },
};

obj.foo();

22.2.2 메서드 호출

메소드를 호출한 객체가 바인딩 됨

const obj = {
  gender: 'M',
  foo() {
    console.log(this);
  },
};

const obj2 = {
  gender: 'F',
};
obj2.foo = obj.foo;

obj2.foo(); // {gender: 'F', foo: ƒ}

22.2.3 생성자 함수 호출

생성자 함수가 생성할 인스턴스가 바인딩 됨

function Circle(radius) {
  this.radius = radius;
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}

const circle = new Circle(5);
console.log(circle.getDiameter()); // 10

22.2.4 Function.prototype.apply/call/bind 메서드에 의한 간접 호출

  • apply/call
    • this로 사용할 객체와 인수들을 전달받아 함수를 호출함
    • arguments와 같은 유사 배열 객체에 대해 배열 메소드를 호출할 때 주로 사용함
function printThis() {
  console.log(this, arguments);
}

const thisArg = { a: 1 };

printThis.apply(thisArg, [1, 2, 3]); // {a: 1} Arguments(3) [1, 2, 3, callee: (...), Symbol(Symbol.iterator): ƒ]
printThis.call(thisArg, 1, 2, 3); // {a: 1} Arguments(3) [1, 2, 3, callee: (...), Symbol(Symbol.iterator): ƒ]
function convertArgsToArray() {
  return Array.prototype.map.call(arguments, arg => arg * 2);
}

console.log(convertArgsToArray(1, 2, 3)); // [2, 4, 6]
  • bind
    • 인수로 전달된 객체로 this 바인딩이 교체된 새로운 함수를 반환함
function printThis() {
  console.log(this);
}

const thisArg = { a: 1 };

printThis.bind(thisArg)(); // {a: 1}

0개의 댓글