this

Seongkyun Yu·2020년 12월 7일
0

TIL - Javascript

목록 보기
18/28

기존 블로그에 작성한 내용을 velog로 이전한 글입니다


1. this

  • 자신이 속한 객체를 참조하기 위한 키워드

  • 함수가 호출되는 방식에 따라 this에 바인딩될 값, 즉 this 바인딩이 동적으로 결정된다.

    // this는 어디서든지 참조 가능하다.
    // 전역에서 this는 전역 객체 window를 가리킨다.
    console.log(this); // window
    
    function square(number) {
      // 일반 함수 내부에서 this는 전역 객체 window를 가리킨다.
      console.log(this); // window
      return number * number;
    }
    square(2);
    
    const person = {
      name: "Lee",
      getName() {
        // 메소드 내부에서 this는 메소드를 호출한 객체를 가리킨다.
        console.log(this); // {name: "Lee", getName: ƒ}
        return this.name;
      },
    };
    console.log(person.getName()); // Lee
    
    function Person(name) {
      // 생성자 함수 내부에서 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
      console.log(this); // Person { name: "Lee" }
      this.name = name;
    }
    
    const me = new Person("Lee");

2. 함수 호출 방식과 this 바인딩


함수 호출 방식this 바인딩
일반 함수 호출전역 객체
메소드 호출메소드를 호출한 객체
생성자 함수 호출생성자 함수가 (미래에) 생성할 인스턴스
Function.prototype.apply/call/bind 메소드에 의한 간접 호출Function.prototype.apply/call/bind 메소드에 인자로 전달한 객체

  • 일반 함수 호출 : 기본적으로 전역 객체가 바인딩 된다.

  • 메소드 호출 : 메소드를 호출한 객체가 바인딩 된다. (소유와 관계 없다)


  • 생성자 함수 호출 :

    생성자 함수 내부의 this에는 생성자 함수가 (미래에) 생성할 인스턴스가 바인딩된다.

    // 생성자 함수
    function DiscountPrice(price) {
      // 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
      this.price = price;
      this.getDiscountPirce = function () {
        return 0.9 * this.price;
      };
    }
    
    // 인스턴스의 생성
    // 1000원인 상품 객체 생성
    const price = new DiscountPrice(1000);
    // 5000원인 상품 객체 생성
    const price2 = new DiscountPrice(5000);
    
    console.log(price.getDiscountPirce()); // 900
    console.log(price2.getDiscountPirce()); // 4500

// new 연산자와 함께 호출하지 않으면 생성자 함수로 동작하지 않는다.
// 즉, 일반적인 함수의 호출이다.
const price3 = DiscountPrice(15000);

// 일반 함수 DiscountPrice은 반환문이 없으므로 암묵적으로 undefined를 반환한다.
console.log(price3); // undefined

// 일반 함수 DiscountPrice내의 this는 전역 객체를 가리킨다.
console.log(price); // 15000

<br>

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

```javascript
함수.apply(this로바인딩될객체, [인수들]);         // 실행까지 됨
함수.call(this로바인딩될객체, 인수, 인수, 인수);  // 실행까지 됨
함수.bind(this로바인딩될객체);                   // 실행은 안됨

apply와 call 메소드의 본질적인 기능은 함수를 호출하는 것
apply와 call 메소드는 함수를 호출하면서 첫번째 인수로 전달한 특정 객체를 호출한 함수의 this에 바인딩한다.
주로 arguments 객체와 같은 유사 배열 객체에 배열 메소드를 사용하기 위해 쓴다.

function convertArgsToArray() {
  console.log(arguments);

  // arguments 객체를 배열로 변환
  // slice: 배열의 특정 부분에 대한 복사본을 생성한다.
  const arr = Array.prototype.slice.apply(arguments);
  // const arr = Array.prototype.slice.call(arguments);
  console.log(arr);

  return arr;
}

convertArgsToArray(1, 2, 3); // [ 1, 2, 3 ]

bind 메소드는 메소드의 this와 메소드 내부의 중첩 함수 또는 콜백 함수의 this가 불일치하는 문제를 해결하기 위해 사용된다.

function Person(name) {
  this.name = name;
}

Person.prototype.doSomething = function (callback) {
  callback.bind(this)();
  // callback.apply(this);
  // callback.call(this);
};

function foo() {
  console.log(this.name); // ②
}

const person = new Person("Lee");

person.doSomething(foo); // Lee

3. 프로퍼티 위치 결정

  • 개별적인 속성이 필요한 경우 this.속성 으로 프로퍼티 추가

  • 개별적 속성을 활용한 메서드일 경우 .prototype에 추가

  • 개별적 속성이 필요 없는 메소드는 정적 메소드를 사용한다.


참고자료: poiemaweb.com

profile
FrontEnd Developer

0개의 댓글