Function.prototype
은 함수 객체들의 부모 역할을 하는 프로토타입 객체이다.
function hello(){
console.log('hello');
}
다음과 같은 코드가 있다면,
hello.__proto__
를 통해, 프로토타입 객체를 추적해보면 Function.prototype()
이 나온다.
고로, Function.prototype()
에서 정의하는 프로퍼티들은 모든 함수객체에서 사용할 수 있는데, 그 중 하나가 call
프로퍼티다.
A.B.call(C, D)
코드는 다음과 같이 써지는데, A는 객체, B는 함수, C는 객체, D는 인수이다.
이게 어떤 의미냐면, A에 있는 B라는 메소드를 C가 가져다 쓴다는 의미이다.
var b = {
name: 'Steve',
age: 25,
greeting: function(){
console.log(this.name, this.age);
}
}
다음과 같은 코드가 있다고 가정해보자
여기서 b.greeting()
을 할 경우,
Steve 25
라고 출력이 되는데, 다음의 경우는 어떨까?
var c = {
name: 'Peter',
age: 21
};
는 c.greeting()
을 하면 다음과 같은 오류가 발생한다.
VM1359:1 Uncaught TypeError: c.greeting is not a function
즉, c에서는 greeting이란 프로퍼티가 없어 함수가 정의되어있지 않다고 오류가 난다는 것이다.
그런데, 이때 call
을 사용해보자.
b.greeting.call(c);
그럼 놀랍게도 다음과 같은 값이 출력된다.
Peter 21
c에는 greeting이 없는데도 다음처럼 결과값이 출력이 되는 것이다.
function sayHi(name, age){
console.log(`Hi! I'm ${name} and ${age}!`);
}
다음과 같은 함수도 마찬가지로, 가져다 쓸 수 있는데 그 이유는 모든 전역 함수
는 window
객체의 프로퍼티이기 때문이다.
window.sayHi.call(c, c.name, c.age);
원래는 다음과 같은데, window는 전역객체라 생략이 가능해서
sayHi.call(c, c.name, c.age); // 결과 => Hi! I'm Peter and 21!
다음처럼 호출 할 수 있다는 것이다.
이 부분은 다음처럼도 사용이 가능하다.
function sayHi(){
console.log(`Hi! I'm ${this.name} and ${this.age}!`);
}
sayHi.call(c); // 결과 => Hi! I'm Peter and 21!
sayHi(); // 결과 => Hi! I'm and undefined!"
다음과 같은 코드가 있다고 가정해보자.
var hasMatch = Array.prototype.indexOf.call(potentialElements, targetElement) >= 0;
여기서 참고로 potentialElements
는 NodeList로 유사배열 객체이지만, 배열은 아니다.
하지만 Array.prototype.indexOf.call
을 통해 배열에서 사용할 수 있는 indexOf()를 사용할 수 있게 되는 것이다.
이런식으로 내가 직접 객체 안에 메소드로 구현하지 않아도 다른 함수에서 쉽게 가져다 쓸 수 있는데, 이것을 call
이라고 하는 것이다.