객체의 동작을 나타내는 메서드는 자신이 속한 객체의 프로퍼티를 참조하고 변경할 수 있어야 한다
this 바인딩은 함수가 어떻게 호출되었는지에 따라 동적으로 결정된다
function foo(){
console.log("foo's this: ", this); // window
function bar(){
console.log("bar's this: ", this); //window
}
bar();
}
foo();
//해결책
// this를 다른 변수에 할당하여 사용
// 다른 방법으로는 Function.prototype 메서드인 apply, call, bind를 이용하여 간접적으로 this의 바인딩을 설정하는 방법이 있다 이는 뒤에서 설명
var value = 1;
const obj ={
value: 100,
foo() {
const that = this;
setTimeout(function(){
console.log(that.value); //100
},100);
}
}
};
obj.foo();
//이유 예제
const person ={
name: 'lee';
// getname 프로퍼티 -> return this.name 역할을 하는 함수 객체를 가리키고 있다(바인딩)
getNmae() {
return this.name;
}
};
console.log(person.getName()); //lee
//작동 에제
const anotherPerson ={
name:'Kim';
};
anotherPerson.getName = person.getName;
//메서드를 호출하는 객체 = anotherPerson
console.log(anotherPerson.getName()); //Kim
const getName = person.getName;
//일반 함수로 호출 = window 전역 객체
console.log(getName()); //''
function Circle(radius){
this.radius = radius;
this.getDiameter = function (){
return 2 * this.radius;
};
}
const circle1 = new Circle(5);
const circle2 = new Circle(10);
console.log(circle1.getDiameter()); //10
console.log(circle2.getDiameter()); //20
Function.prototype의 메서드이기 때문에 모든 함수가 상속받아 사용할 수 있다
function getThisBinding(){
console.log(arguments);
return this;
}
const thisArg = {a:1};
// 두 번째 인수 전달 방식이 다르다
console.log(getThisBinding.apply(thisArg, [1,2,3]));
// Arguments(3) [1,2,3]
// {a:1}
console.log(getThisBinding.call(thisArg, 1,2,3))
//Arguments(3) [1,2,3]
//{a:1}
function convertArgsToArray(){
console.log(arguments);
// call == apply
// Array.prototype.slice를 인수 없이 호출하면 배열의 복사본을 생성
const arr = Array.prototype.slice.call(arguments);
console.log(arr);
return arr;
}
convertArgsToArray(1,2,3); // [1,2,3]
function getThisBinding(){
return this;
}
const thisArg = {a:1};
console.log(getThisBinding.bind(thisArg)); //getThisBinding
console.log(getThisBinding.bind(thisArg)()); // {a:1} 명시적 호출
const person={
name: 'Lee',
foo(callback){
setTimeout(callback.bind(this), 100);
}
};
person.foo(function(){
console.log(`Hi! my name is ${this.name}.`); // Hi! my name is Lee.
});