[Javascript] Predefined JavaScript Call() Method

studying  · 6 mins read

Call() Method

  • Call() 메서드는 첫 번째 인수로 주어진 “this”값과 나머지 인수와 함께 함수를 호출한다.
  • 어떤 객체는 call method를 사용하여 다른 객체에 속한 method를 사용할 수 있게 된다.

syntax

func.call(thisArg[, arg1[, arg2[, …]]])
thisArg: func 호출에 제공되는 this의 값
arg1, arg2, …: 객체를 위한 인수

예시

예시 1)

const person = {
  fullName: function () {
    return this.firstName + " " + this.lastName;
  },
};

const person1 = {
  firstName: "Aeji",
  lastName: "Jeon",
};

// “Aeji Joen” is returned.
person.fullName.call(person1);

예시 2)

const person = {
  fullName: function (city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  },
};
var person1 = {
  firstName: "Aeji",
  lastName: "Jeon",
};
// “Aeji Joen,Gwangju,Korea” is returned.
person.fullName.call(person1, "Gwangju", "Korea");

예시 3)

var data = "hi";
function display() {
  console.log("data value is %s ", this.data);
}

display.call(); // 'data value is hi' is printed.

예시 3)에서 처럼 owner object를 parameter로 넘겨주지 않고 함수 호출에 call을 사용할 경우 “this” 값은 전역 객체에 바인딩 된다. 하지만 javascript의 strict mode에서 위의 코드에서의 “this”는 undefined 값을 가진다.(주의!)

"use strict";

var data = "hi";

function display() {
  console.log("data value is %s ", this.data);
}

display.call(); // Cannot read the property of 'data' of undefined

매번 call method와 함께 함수를 호출하는 것은 너무 귀찮다.

function hello(thing) {
  console.log("Hello " + thing);
}

hello("world");

javascript에서는 위의 코드에서처럼 보통 call method를 호출하지 않고 괄호 구문을 사용하여 함수를 직접 호출하는데 이는 아래 코드에서 call method를 호출하는 것과 동일하게 수행된다.

hello.call(window, "world");
var person = {
  name: "Aeji Jeon",
  hello: function (thing) {
    console.log(this + " says hello " + thing);
  },
};

person.hello("world");

위의 코드에서는 simple function 호출이 아닌 person이라는 객체에 속해있는 member function을 호출하였다. 이 코드는 global object([object Window])가 아닌 person 객체와 함께 call method가 호출되는 것과 동일하게 수행된다.

person.hello.call(person, "world");
function hello(thing) {
  console.log(this + " says hello " + thing);
}

person = { name: "Aeji Jeon" };
person.hello = hello;

person.hello("world");
// person.hello.call(person, "world")

hello("world");
// hello.call(window, "world");
// "[object DOMWindow]world"

위의 코드에서처럼 함수는 한 번 참조된 “this”에 대해 지속적으로 기억하지 않고 함수가 호출된 시점에서 호출된 방식에 따라 즉시 “this”가 설정된다.

var person = {
  name: "Aeji Jeon",
  hello: function (thing) {
    console.log(this.name + " says hello " + thing);
  },
};

var bind = function (func, thisValue) {
  return function () {
    return func.apply(thisValue, arguments);
  };
};

var boundHello = bind(person.hello, person);
boundHello("world"); // "Aeji Jeon says hello world"
  • arguments: 함수에 전달된 모든 인수를 나타내는 Array 형태의 객체(array 형태라는 것은 arguments가 length 속성과 더불어 0부터 인덱싱이 가능하지만 Array의 forEach, map과 같은 내장 me- apply method: call method와 유사, 차이점은 call() method는 인수를 각각 별개로 받고 apply() method는 인수를 하나의 배열로 사용한다. 여러 개의 인수를 하나의 배열로 사용하려는 경우에 apply method를 사용하면 매우 편리하다.thod를 가지고 있지 않다는 것이다.)
  • apply method: call method와 유사, 차이점은 call() method는 인수를 각각 별개로 받고 apply() method는 인수를 하나의 배열로 사용한다. 여러 개의 인수를 하나의 배열로 사용하려는 경우에 apply method를 사용하면 매우 편리하다.

위의 코드처럼 함수에 persistent한 “this” value를 설정했다. 하지만 boundHello 함수를 호출할 때는

boundHello.call(window, "world");

와 같이 window 객체가 “this” value로 설정되어 호출되고 이후에 우리가 원하는 “this” value인 person 객체로 설정되어 person 객체의 hello method가 호출된다.

ES5에서 위의 코드 동작을 구현하는 bind라는 method를 도입하였다.

  • bind() method를 사용하여 함수에 persistent한 “this” value를 설정하기
var boundHello = person.hello.bind(person);
boundHello("world"); // "Aeji Jeon says hello world"

var person = {
  name: "Aeji Jeon",
  hello: function () {
    console.log(this.name + " says hello world");
  },
};

$("#some-div").click(person.hello.bind(person));

// div elemement가 클릭될 때마다
// "Aeji Jeon says hello world"가 출력 됨.

bind() method는 위의 코드에서처럼 callback으로 전달할 raw function이 필요할 때 유용하다.

references

  • https://www.w3schools.com/js/js_function_call.asp
  • https://www.w3schools.com/js/js_function_apply.asp
  • https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/arguments
  • https://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/