22장 this

자바 스크립트에서의 this에 대해서 알아보자.

22.1 this 키워드

const circle = {
// 프로퍼티: 객체 고유의 상태 데이터 
radius: 5,
// 메서드: 상태 데이터를 참조하고 조작하는 동작 
getDiameter() {
// 이 메서드가 자신이 속한 객체의 프로퍼티나 다른 메서드를 참조하려면
// 자신이 속한 객체인 circle을 참조할 수 있어야 한다.
return 2 * circle.radius; 
    }
}
console.log(circle.getDiameter()); // 10
// 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: f}
    return this.name;
    }
}
console.log(person.getName()); // Lee
    function Person(name) {
    this.name = name;
    // 생성자 함수 내부에서 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
    console.log(this); // Person {name: "Lee"}
}
const me = new Person('Lee');

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

  1. 일반 함수 호출
  2. 메서드호출
  3. 생성자 함수 호출
  4. Function.prototype.apply/call/bind 메서드에 의한 간접 호출

22.2.1 일반 함수 호출

function foo() {
    console.log("foo's this: ", this); // window
    function bar() {
    console.log("bar's this: ", this); // window
    }
    bar();
}
foo();

22.2.2 메서드 호출

22.2.3 생성자 호출

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

/**
* 주어진 this 바인딩과 인수 리스드 배열을 사용하여 함수를 호촐한다.
* @param thisArg - this로 사용할 객체
* @param argsArray - 함수에게 전달할 인수 리스트의 배열 또는 유사 배열 객체
* ©returns 호출된 함수의 반환값
*/
Function.prototype.apply(thisArgt, argsArray])
/**
* 주어진 this 바인딩과,로 구분된 인수 리스트를 사용하여 함수를 호출한다.
* @param thisArg - this로 사용할 객체
* @param argl, arg2, ... - 함수에게 전달할 인수 리스트
* ©returns 호출된 함수의 반환값
*/
Function.prototype.call (thisArg[, argl[, arg2[, ... ]]])

function getThisBinding() {
    console.log(arguments);
    return this;
}
// this로 사용할 객체
const thisArg = { a 1 };
// getThisBinding 함수를 호출하면서 인수로 전달한 객체를 getThisBinding 함수의 this에 바인딩한다.
// apply 메서드는 호출할 함수의 인수를 배열로 묶어 전달한다.
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
// Arguments(3) [1, 2, 3, callee: f, Symbol(Symbol.iterator): f]
// {a: 1}
// call 메서드는 호출할 함수의 인수를 쉼표로 구분한 리스트 형식으로 전달한다.
console.log(getThisBinding.call(thisArg, 1, 2, 3));
// Arguments(3) [1, 2, 3, callee: f, Symbol(5ymbol.iterator): f]
// {a: 1}

function getThisBinding() {
    return this;
}
// this로 사용할 객체
const thisArg = { a: 1 };
// bind 메서드는 첫 번째 인수로 전달한 thisArg로 this 바인딩이 교체된
// getThisBinding 함수를 새롭게 생성해 반환한다.
console.log(getThisBinding.bind(thisArg)); // getThisBinding
// bind 메서드는 함수를 호출하지는 않으므로 명시적으로 호출해야 한다.
console.log(getThisBinding.bind(thisArg)()); // {a: 1}

const person = {
    name: 'Lee' ,
    foo(callback) {
        // 1
        setTimeout(callback, 100);
    }
};
person.foo(function () {
    console.log( 'Hi! my name is ${this.name}.' );  // 2
}

const person = {
    name: 'Lee' ,
    foo(callback) {
        // bind 메서드로 callback 함수 내부의 this 바인딩
        setTimeout(callback.bind(this), 100);
    }
};
person.foo(function () {
    console.log( 'Hi! my name is ${this.name}.' );  // Hi! my name is Lee.
}

끝!