this

Posted by Seongkyun Yu on 2020-03-06
Estimated Reading Time 3 Minutes
Words 517 In Total
Viewed Times

1. this

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // 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에는 생성자 함수가 (미래에) 생성할 인스턴스가 바인딩된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // 생성자 함수
    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

1
2
3
4
5
6
7
8
<br>

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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가 불일치하는 문제를 해결하기 위해 사용된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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


If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !