Function.prototype.call()

박종한·2020년 3월 19일
2

Javascript

목록 보기
2/2

Function.prototype은 함수 객체들의 부모 역할을 하는 프로토타입 객체이다.

function hello(){
  console.log('hello');
}

다음과 같은 코드가 있다면,

hello.__proto__

를 통해, 프로토타입 객체를 추적해보면 Function.prototype()이 나온다.

고로, Function.prototype()에서 정의하는 프로퍼티들은 모든 함수객체에서 사용할 수 있는데, 그 중 하나가 call 프로퍼티다.

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이라고 하는 것이다.

profile
코딩의 고수가 되고 싶은 종한이

0개의 댓글