call()
메서드는 함수를 호출하는 방법 중 하나로, 특정 객체에서 함수를 호출하면서 this
값을 설정할 수 있다. call()
메서드는 함수
와 함께 사용되며, 함수의 첫번째 인자로 객체를 받는다. 이렇게 하므로써 함수 내부에 this
를 지정된 객체로 설정할 수 있다.
functionName.call(thisArg, arg1, arg2, ...);
functionName
: thisArg에서 호출할 함수의 이름 또는 참조thisArg
: 함수 내에서 this로 사용될 객체arg1, arg2...
: 호출할 함수에 전달할 인자call()
메서드를 사용하면 함수를 호출하는 동시에 this
값을 지정한 객체로 설정할 수 있다. 이는 함수를 해당 객체의 메서드로서 호출하는 것과 동일한 효과가 있다.
var person = {
name : "Alice",
greet : function(){
console.log("hello"+this.name);
}
};
var anotherPerson = {
name : 'Bob'
};
person.greet() ; // 출력 : hello Alice
person.greet.call(anotherPerson) // 출력 : hello Bob
call()
메서드를 사용해서 person.greet.call(anotherPerson)
처럼 호출할 경우, greet()
함수의 this
값을 anotherPerson
객체로 설정한다.
이처럼 call()
메서드는 함수를 호출할 때 this
값을 지정하는데 유용하게 사용될 수 있다. 다형성과 상속등의 개념을 구현할 때 유용하다.
간혹 수신자 객체의 프로퍼티는 아니지만 수신자 객체를 특정 객체로 지정해 함수를 호출할 필요가 있을 수도 있다. 즉 A 객체의 프로퍼티함수지만 B객체에서 그 함수를 사용하고 싶을 수 있다는 말이다. 물론 다음과 같이 그 메서드를 해당 객체에 새로운 프로퍼티로써 추가할 수 도 있다.
obj.temporary = f;
var result = obj.temporary(arg1, arg2, arg3);
delete obj.temporary;
이런 접근 방법은 그다지 좋지 않다. obj
에 temporary
객체가 이미 존재할경우 충돌할 수 있다. 게다가 예약어는 추가를 금지하기도 한다. 즉 이렇게 임시적으로 추가하는것은 좋지 못하다.
이때 call() 함수를 사용하게 된다.
f.call(obj,arg1,arg2,arg3);
첫번째 인자로 수신자 객체를 전달하는것 말고는 함수를 직접 호출하는것과 비슷하다. 이처럼 call() 메서드는 삭제, 수정, 오버라이딩된 메서드를 호출하는데 도움이 된다.
javascript 객체의 메서드로, 객체가 특정 속성을 직접 소유하고 있는지 여부를 확인하는데 사용됩니다.
var person = {
name: 'Alice',
age: 25
};
console.log(person.hasOwnProperty('name')); // 출력: true
console.log(person.hasOwnProperty('age')); // 출력: true
console.log(person.hasOwnProperty('gender')); // 출력: false
hasOwnProperty
메서드의 call
메서드를 사용하면 , 해당 딕셔너리 객체내에 저장되어 있지 않은 메서드라도 호출하라 수 있다.
var hasOwnProperty = ().hasOwnProperty // 함수를 변수에 저장
dict.too = 1; //프로퍼티 추가
delete dict.hasOwnProperty; // hasOwnProperty는 객체가 기본적으로 가지고 있는 메서드이다. 근데 삭제함
hasOwnProperty.call(dict, "foo") // true;
hasOwnProperty.call(dict, "hasOwnProperty") // false;
call()
메서드로 인해 hasOwnProperty
내부에 있는 this
를 dict
으로 바인딩 할 수 있어 hasOwnProperty
함수를 그대로 사용할 수 있게 된다.
call()은 고차함수를 정의하는데도 유용하다. 고차 함수를 위한 일반적인 코딩 관례 중 함수를 호출하기 위한 수신자 객체를 부가적인 인자로 받는 방법이 있다.
var table={
entries:[],
addEntry: function(key,value){
this.entries.push({key:key,value:value});
},
forEach:function(f, thisArg){
var entries = this.entries;
for (var i = 0 ;i<entries.length;i++){
var entry = entries[i];
f.call(thisArg, entry.key, entry.value); // 외부함수를 가져와서 사용함
}
}
};
이를 이용해 한 테이블의 내용을 다른 테이블로 간편하게 복사할 수 있다.
table1.forEach(table2.addEntry, table2)
call
을 통해 f
함수 안에있는 this
의 바인딩을 명확하게 해준다.
만약 call
을 사용하지 않고 그냥 table2.addEntry
를 forEach
의 인자로 받는다고 생각해보자
var table={
entries:[],
addEntry: function(key,value){
this.entries.push({key:key,value:value});
},
forEach:function(f){
var entries = this.entries;
for (var i = 0 ;i<entries.length;i++){
var entry = entries[i];
f( entry.key, entry.value, i); // 외부함수를 가져와서 사용함
}
}
};
이렇게 되면 f
즉 table2.addEntry
안에 있는 this
는 전역객체
혹은 undefind
가되어 오류를 발생시킨다.