기존 블로그에 작성한 내용을 velog로 이전한 글입니다
자신이 속한 객체를 참조하기 위한 키워드
함수가 호출되는 방식에 따라 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");
함수 호출 방식 | 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
개별적인 속성이 필요한 경우 this.속성 으로 프로퍼티 추가
개별적 속성을 활용한 메서드일 경우 .prototype에 추가
개별적 속성이 필요 없는 메소드는 정적 메소드를 사용한다.