통화와 적용의 차이점은 무엇입니까?


3103

함수 사용 call과 apply호출 의 차이점은 무엇입니까 ?

var func = function() {
  alert('hello!');
};

func.apply(); vs func.call();

위에서 언급 한 두 가지 방법간에 성능 차이가 있습니까? 언제 call이상 을 사용 하는 것이 가장 apply좋습니까?


727
arg의 a배열을 적용하고 arg의 c열을 요구하는 것을 생각하십시오 .
— 래리 배틀

176
@LarryBattle 나는 거의 동일하지만 a는 배열과 c를 쉼표 (예 : 쉼표로 구분 된 인수)에 적용한다고 생각합니다.
— Samih

3
나는 그것이 바보라는 데 동의합니다. 성가신 것은 어떤 영향을 미치는 asked이 질문을 중요한 js 질문 목록에 추가했기 때문에 인터뷰 중에이 질문이 어떻게 든 묻는 것입니다.
— Ringo

6
당신은 적용 번 작업 (하나 개의 인수), 당신 [전화]에 대한 호출 사람들이 많은 시간 (몇 가지 인수). 대안 : Call of Duty 게임이 너무 많습니다 .
— Gras Double

1
"this"값에 관계없이 인수 값 목록을 사용하여 가변 함수를 호출하려는 경우 ES6 스프레드 연산자를 사용하십시오 (예 : fn(...input)입력이 배열 인 경우). developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
— Gajus

답변:


3648

차이점은 배열로 apply함수를 호출 할 수 있다는 것입니다 arguments. call매개 변수를 명시 적으로 나열해야합니다. 유용한 니모닉은 " 에 대한 rray와 C 에 대한 C OMMA."

apply and call 에 대한 MDN 설명서를 참조하십시오 .

의사 구문 :

theFunction.apply(valueForThis, arrayOfArgs)

theFunction.call(valueForThis, arg1, arg2, ...)

또한 ES6부터 함수 spread와 함께 사용할 수 있는 배열 가능성이 있습니다 . 여기서call 호환성을 확인할 수 있습니다 .

샘플 코드 :

function theFunction(name, profession) {
    console.log("My name is " + name + " and I am a " + profession +".");
}
theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]);
theFunction.call(undefined, "Claude", "mathematician");
theFunction.call(undefined, ...["Matthew", "physicist"]); // used with the spread operator


25
추가해야 할 것은 인수가 숫자 형 배열 ([])이어야한다는 것입니다. 연관 배열 ({})이 작동하지 않습니다.
— 케빈 슈뢰더

326
@KevinSchroeder : 스크립트 용어로, []라고 배열 , {}라고 개체 .
— Martijn

89
나는 종종 배열을 취하는 것을 잊어 버렸고 인수를 나열 할 것을 기대했습니다. 와 방법 시작의 첫 글자 만약 내가 기억하는 데 사용되는 기술이다 a는 그 때, 즉 배열을 취하는 pply 배열
— 아지즈 punjani

16
사용 @SAM 전화를 당신의 값 변경해야하는 경우 일반 함수 호출 대신에만 의미가 이 함수 호출. 함수 arguments-object를 배열로 변환하는 예제 : Array.prototype.slice.call(arguments)또는 [].slice.call(arguments). 예를 들어, 거의 동일한 매개 변수를 사용하여 다른 함수를 호출하는 함수와 같이 배열에 인수가있는 경우 apply 가 의미가 있습니다. 권장 사용 일반 함수 호출 funcname(arg1)이 필요한 것을 수행하고 저장하면 전화 및 적용 당신이 정말로 필요할 때 그 특별한 경우를 위해.
— 약

4
@KunalSingh 모두 call와 apply두 개의 매개 변수를 사용합니다. apply' and call 함수 의 첫 번째 인수는 소유자 객체 여야하고 두 번째 매개 변수는 각각 배열 또는 쉼표로 구분 된 매개 변수입니다. 엄격하지 않은 모드에서 null또는 undefined첫 번째 인수로 전달하면 전역 객체로 대체됩니다.window
— AJ Qarshi

229

K. Scott Allen 은이 문제에 대해 좋은 글 을 남겼 습니다.

기본적으로 함수 인수를 처리하는 방법이 다릅니다.

apply () 메서드는 call ()과 동일하지만 apply ()에는 두 번째 매개 변수로 배열이 필요합니다. 배열은 대상 메소드의 인수를 나타냅니다. "

그래서:

// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);

42
apply () 및 call ()의 두 번째 매개 변수는 선택 사항이며 필수는 아닙니다.
— 화난 키위

34
첫 번째 매개 변수도 필요하지 않습니다.
— Ikrom

@Ikrom, 첫 번째 매개 변수는 필수는 call아니지만apply
— –caster

160

각 함수의 사용시기에 대한 부분에 대답하려면 apply전달할 인수의 수를 모르거나 인수가 이미 배열 또는 배열과 같은 오브젝트 ( arguments자신의 인수를 전달 하는 오브젝트)에있는 경우 사용하십시오. call인수를 배열로 랩핑 할 필요가 없으므로 그렇지 않으면 사용하십시오 .

f.call(thisObject, a, b, c); // Fixed number of arguments

f.apply(thisObject, arguments); // Forward this function's arguments

var args = [];
while (...) {
    args.push(some_value());
}
f.apply(thisObject, args); // Unknown number of arguments

예를 들어 인수를 전달하지 않으면 함수를 호출 하기 call때문에 선호 합니다. 존재하지 않는 인수에 함수를 적용 하고 있음을 의미합니다 .apply

apply인수를 사용하여 배열에서 래핑하는 경우 (예 : f.apply(thisObject, [a, b, c])대신 f.call(thisObject, a, b, c))를 제외하고는 성능 차이가 없어야합니다 . 나는 그것을 테스트하지 않았으므로 차이점이있을 수 있지만 브라우저마다 매우 다를 수 있습니다. 그것은 가능성이 높습니다 call이미 배열의 인수를하지 않는 경우입니다 빠른 apply입니다 빨리 당신이 할 경우.


111

좋은 니모닉이 있습니다. pply는 사용 rrays 및 의 법이지는 하나 개 또는 두 개의 인수를 사용합니다. 당신이 사용하는 경우 C를 당신이 가지고있는 모든 C는 인수의 수를 ount.


2
유용한 니모닉!. 첫 번째 또는 두 번째 매개 변수 apply가 모두 필요 하지 않으므로 '하나 또는 두 개의 인수'를 '최대 두 개의 인수' 로 변경합니다. 왜 매개 변수를 호출 apply하거나 호출하지 않는지 확실하지 않습니다 call. 누군가가 왜 여기에 있는지 알아 보려고하는 것 같습니다. stackoverflow.com/questions/15903782/…
— dantheta

92

이것은 오래된 주제이지만 .call이 .apply보다 약간 빠르다는 것을 지적하고 싶었습니다. 왜 그런지 정확히 말할 수 없습니다.

jsPerf, http://jsperf.com/test-call-vs-apply/3 참조


[ UPDATE!]

Douglas Crockford는 성능 차이를 설명하는 데 도움이되는 두 가지 차이점을 간략하게 언급합니다 ... http://youtu.be/ya4UHuXNygM?t=15m52s

Apply는 인수의 배열을 취하지 만 Call은 0 개 이상의 개별 매개 변수를 사용합니다! 아하!

.apply(this, [...])

.call(this, param1, param2, param3, param4...)


이것은 함수가 매개 변수 / 배열로 무엇을하는지에 달려 있습니다. 배열을 처리 할 필요가 없다면 시간이 덜 걸리나요?
— Eric Hodonsky

12
흥미롭게도 어레이가 없어도 통화 속도는 훨씬 빠릅니다. jsperf.com/applyvscallvsfn2
— Josh Mc

@JoshMc 브라우저마다 매우 다릅니다. IE 11에서는 통화보다 두 배 빠르게 적용됩니다.
— Vincent McNabb

1
1. 새 배열을 만들면 가비지 수집기가 특정 시점에서 배열을 정리해야합니다. 2. 역 참조를 사용하여 배열의 항목에 액세스하는 것은 변수 (매개 변수)에 직접 액세스하는 것보다 덜 효율적입니다. (이것은 kmatheny가 "구문 분석 (parsing)"의 의미라고 믿습니다. 실제로는 상당히 다릅니다.) 그러나 나의 주장 중 어느 것도 jsperf를 설명하지 않습니다. 이는 두 함수의 엔진 구현과 관련이 있어야합니다. 예를 들어 전달되지 않은 경우 어쨌든 빈 배열을 만듭니다.
— joeytwiddle

테스트 및 비디오를 공유해 주셔서 감사합니다
— Gary

76

Michael Bolin의 Closure : The Definitive Guide 에서 발췌 한 내용 입니다. 약간 길어 보일 수 있지만 통찰력이 풍부합니다. "부록 B. 자주 JavaScript 개념을 오해":


어떤 this함수가 호출되는 경우를 말합니다

형식의 함수를 호출 할 때 foo.bar.baz()객체를 foo.bar수신자라고합니다. 함수가 호출되면 다음 값으로 사용되는 수신자입니다 this.

var obj = {};
obj.value = 10;
/** @param {...number} additionalValues */
obj.addValues = function(additionalValues) {
  for (var i = 0; i < arguments.length; i++) {
    this.value += arguments[i];
  }
  return this.value;
};
// Evaluates to 30 because obj is used as the value for 'this' when
// obj.addValues() is called, so obj.value becomes 10 + 20.
obj.addValues(20);

함수가 호출 될 때 명시적인 수신자가 없으면 전역 오브젝트가 수신자가됩니다. 47 페이지의 "goog.global"에서 설명한대로 window는 웹 브라우저에서 JavaScript가 실행될 때 전역 객체입니다. 이것은 놀라운 행동으로 이어진다 :

var f = obj.addValues;
// Evaluates to NaN because window is used as the value for 'this' when
// f() is called. Because and window.value is undefined, adding a number to
// it results in NaN.
f(20);
// This also has the unintentional side effect of adding a value to window:
alert(window.value); // Alerts NaN

비록 obj.addValues와 f동일한 기능을 참조하십시오, 그들은 수신기의 값이 각 통화에서 다르기 때문에 전화했을 때 다르게 동작합니다. 따라서을 참조하는 함수를 호출 할 때 호출 될 때 올바른 값 this을 갖도록하는 것이 중요합니다 this. 명확하게 말하면 this함수 본문에서 참조되지 않은 경우 동작 f(20)과 obj.addValues(20)동일합니다.

함수는 JavaScript에서 일류 객체이므로 자체 메서드를 가질 수 있습니다. 모든 함수에는 메소드가 call()있으며 함수를 호출 할 때 apply()수신자 (즉, 참조하는 오브젝트)를 재정의 할 수 this있습니다. 메소드 서명은 다음과 같습니다.

/**
* @param {*=} receiver to substitute for 'this'
* @param {...} parameters to use as arguments to the function
*/
Function.prototype.call;
/**
* @param {*=} receiver to substitute for 'this'
* @param {Array} parameters to use as arguments to the function
*/
Function.prototype.apply;

참고 유일한 차이 call()및 apply()그 인 call()반면, 각각의 인자로서의 기능 파라미터를 수신하는 apply()단일 어레이로 수신 :

// When f is called with obj as its receiver, it behaves the same as calling
// obj.addValues(). Both of the following increase obj.value by 60:
f.call(obj, 10, 20, 30);
f.apply(obj, [10, 20, 30]);

로 다음의 호출은, 동등 f하고 obj.addValues동일한 기능을 참조하십시오

obj.addValues.call(obj, 10, 20, 30);
obj.addValues.apply(obj, [10, 20, 30]);

그러나 수신자 인수가 지정되지 않은 경우 수신자 인수를 대체하기 위해 자체 수신자의 값을 사용 call()하거나 apply()사용 하지 않기 때문에 다음이 작동하지 않습니다.

// Both statements evaluate to NaN
obj.addValues.call(undefined, 10, 20, 30);
obj.addValues.apply(undefined, [10, 20, 30]);

의 값은 this절대 null또는 undefined함수가 호출 될 수 없습니다 . 경우 null또는 undefined받는 수신기로 공급된다 call()또는 apply()전역 객체 대신에 수신기에 대한 값으로서 사용된다. 따라서 앞의 코드는 value전역 개체에 이름이 지정된 속성을 추가 할 때와 동일한 바람직하지 않은 부작용이 있습니다.

함수가 할당 된 변수에 대한 지식이없는 것으로 생각하면 도움이 될 수 있습니다. 이는 함수가 정의 될 때가 아니라 함수가 호출 될 때이 값이 바인드 될 것이라는 아이디어를 강화하는 데 도움이됩니다.


추출물의 끝.


사실 additionalValues은 obj.addValues몸 안에서 언급되지 않습니다
— Viktor Stolbin

나는 당신이 질문에 대답하고 있다는 것을 알고 있지만 추가하고 싶습니다 : f를 정의 할 때 bind를 사용할 수 있습니다. var f = obj.addValues;되고 var f = obj.addValues.bind(obj) 지금 사용 호출하지 않고 일을하거나 할 때마다 적용됩니다 (20) 바.
— jhliberty

나는 당신이 그것을 쓰지 않았다는 것을 알고 있지만, 당신은 그 책의 글과 예제를 관련성있게 강조했으며 매우 감사합니다. 그들은 매우 도움이되었습니다.
— Fralcon

34

때로는 한 객체가 다른 객체의 기능을 빌리는 것이 유용합니다. 즉, 빌린 객체는 빌려 진 함수를 마치 마치 마치 마치 마치 마치 마치 마치 자신의 함수처럼 실행합니다.

작은 코드 예 :

var friend = {
    car: false,
    lendCar: function ( canLend ){
      this.car = canLend;
 }

}; 

var me = {
    car: false,
    gotCar: function(){
      return this.car === true;
  }
};

console.log(me.gotCar()); // false

friend.lendCar.call(me, true); 

console.log(me.gotCar()); // true

friend.lendCar.apply(me, [false]);

console.log(me.gotCar()); // false

이 메소드는 객체에 임시 기능을 제공하는 데 매우 유용합니다.


1
console.log확인 방법을 알고 싶은 사람들에게 : console.log 란 무엇이며 어떻게 사용합니까?
— Michel Ayres 2019

25

Call, Apply 및 Bind의 또 다른 예입니다. Call과 Apply의 차이점은 분명하지만 Bind 는 다음과 같이 작동합니다.

  1. 바인드는 실행될 수있는 함수의 인스턴스를 반환합니다.
  2. 첫 번째 매개 변수는 ' this '입니다
  3. 두 번째 매개 변수는 쉼표로 구분 된 인수 목록입니다 (예 : Call )

}

function Person(name) {
    this.name = name; 
}
Person.prototype.getName = function(a,b) { 
     return this.name + " " + a + " " + b; 
}

var reader = new Person('John Smith');

reader.getName = function() {
   // Apply and Call executes the function and returns value

   // Also notice the different ways of extracting 'getName' prototype
   var baseName = Object.getPrototypeOf(this).getName.apply(this,["is a", "boy"]);
   console.log("Apply: " + baseName);

   var baseName = Object.getPrototypeOf(reader).getName.call(this, "is a", "boy"); 
   console.log("Call: " + baseName);

   // Bind returns function which can be invoked
   var baseName = Person.prototype.getName.bind(this, "is a", "boy"); 
   console.log("Bind: " + baseName());
}

reader.getName();
/* Output
Apply: John Smith is a boy
Call: John Smith is a boy
Bind: John Smith is a boy
*/

23

'valueForThis'인수가 사용되는 예제를 보여주고 싶습니다.

Array.prototype.push = function(element) {
   /*
   Native code*, that uses 'this'       
   this.put(element);
   */
}
var array = [];
array.push(1);
array.push.apply(array,[2,3]);
Array.prototype.push.apply(array,[4,5]);
array.push.call(array,6,7);
Array.prototype.push.call(array,8,9);
//[1, 2, 3, 4, 5, 6, 7, 8, 9] 

** 세부 사항 : http://es5.github.io/#x15.4.4.7 *


20

Call ()은 쉼표로 구분 된 인수를 사용합니다 (예 :

.call(scope, arg1, arg2, arg3)

apply ()는 인수의 배열을 취합니다. 예 :

.apply(scope, [arg1, arg2, arg3])

몇 가지 사용 예는 다음과 같습니다. http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/


`// call () === 쉼표로 구분 된 인수 (인수-목록) .call (this, args1, args2, args3, ...) // apply () === 인수 배열 (배열 항목). apply (this, [arr0, arr1, arr2, ...])`
— xgqfrms

19

에서 Function.prototype.apply의 ()에 MDN 워드 프로세서 :

apply () 메소드는 주어진 this값과 인수를 배열 (또는 배열과 같은 객체)로 제공 하는 함수를 호출합니다 .

통사론

fun.apply(thisArg, [argsArray])

에서 Function.prototype.call ()에 MDN 워드 프로세서 :

call () 메소드는 주어진 this값과 인수가 개별적으로 제공되는 함수를 호출합니다 .

통사론

fun.call(thisArg[, arg1[, arg2[, ...]]])

에서 자바 스크립트에서 Function.apply에와 Function.call :

apply () 메서드는 call ()과 동일하지만 apply ()에는 두 번째 매개 변수로 배열이 필요합니다. 배열은 대상 메소드의 인수를 나타냅니다.


코드 예 :

var doSomething = function() {
    var arr = [];
    for(i in arguments) {
        if(typeof this[arguments[i]] !== 'undefined') {
            arr.push(this[arguments[i]]);
        }
    }
    return arr;
}

var output = function(position, obj) {
    document.body.innerHTML += '<h3>output ' + position + '</h3>' + JSON.stringify(obj) + '\n<br>\n<br><hr>';
}

output(1, doSomething(
    'one',
    'two',
    'two',
    'one'
));

output(2, doSomething.apply({one : 'Steven', two : 'Jane'}, [
    'one',
    'two',
    'two',
    'one'
]));

output(3, doSomething.call({one : 'Steven', two : 'Jane'},
    'one',
    'two',
    'two',
    'one'
));

이 바이올린을 참조하십시오 .



10

여기에 작은 글이 있습니다.

http://sizeableidea.com/call-versus-apply-javascript/

var obj1 = { which : "obj1" },
obj2 = { which : "obj2" };

function execute(arg1, arg2){
    console.log(this.which, arg1, arg2);
}

//using call
execute.call(obj1, "dan", "stanhope");
//output: obj1 dan stanhope

//using apply
execute.apply(obj2, ["dan", "stanhope"]);
//output: obj2 dan stanhope

//using old school
execute("dan", "stanhope");
//output: undefined "dan" "stanhope"

여기 또 다른 하나가 있습니다 : blog.i-evaluation.com/2012/08/15/javascript-call-and-apply 그러나 기본적으로 옳습니다 : .call (scope, arg1, arg2, arg3)
— Mark Karwowski


6

다음과 같이 통화 및 적용 방법을 차별화 할 수 있습니다

CALL : 인수가있는 함수는 개별적으로 제공합니다. 전달할 인수를 알고 있거나 전달할 인수가 없으면 call을 사용할 수 있습니다.

적용 : 배열로 제공된 인수로 함수를 호출합니다. 함수에 몇 개의 인수를 전달할지 모르는 경우 apply를 사용할 수 있습니다.

apply over call을 사용하면 이점이 있습니다. 전달 된 배열 만 변경할 수있는 인수 수만 변경할 필요는 없습니다.

성능에는 큰 차이가 없습니다. 그러나 배열이 apply 메소드에서 평가되어야하기 때문에 적용에 비해 호출이 조금 더 빠르다고 말할 수 있습니다.


5

이들과 메소드의 차이점은 매개 변수 전달 방법입니다.

“배열의 경우 A와 쉼표의 경우 C”는 편리한 니모닉입니다.


11
이 답변은 다른 답변에 아직 제공되지 않은 내용을 제공합니까?
— Kyll

5

this함수가 실행될 때 값 을 강제하기 위해 호출 및 적용 둘 다 사용됩니다 . 유일한 차이점은 1이 and 인 인수 를 call취 한다는 것 입니다. 두 개의 인수 만 사용합니다. 하나는 다른 하나 는 인수 배열입니다.n+1this'n' argumentsapplythis

난에 표시되는 장점이 apply이상은 call우리가 쉽게 많은 노력하지 않고 다른 함수에 대한 함수 호출을 위임 할 수 있다는 것입니다;

function sayHello() {
  console.log(this, arguments);
}

function hello() {
  sayHello.apply(this, arguments);
}

var obj = {name: 'my name'}
hello.call(obj, 'some', 'arguments');

hello을 sayHello사용하여 얼마나 쉽게 위임했는지 관찰하십시오 apply. 그러나이 call방법으로는 달성하기가 매우 어렵습니다.


4

그럼에도 불구 call하고 apply같은 것을 달성 하더라도 , 나는 당신이 사용할 수 없지만 사용할 수있는 곳이 적어도 하나 있다고 생각 call합니다 apply. 상속을 지원하고 생성자를 호출하려고 할 때입니다.

다음은 다른 클래스를 확장하여 클래스 작성을 지원하는 클래스를 작성할 수있는 함수입니다.

function makeClass( properties ) {
    var ctor = properties['constructor'] || function(){}
    var Super = properties['extends'];
    var Class = function () {
                 // Here 'call' cannot work, only 'apply' can!!!
                 if(Super)
                    Super.apply(this,arguments);  
                 ctor.apply(this,arguments);
                }
     if(Super){
        Class.prototype = Object.create( Super.prototype );
        Class.prototype.constructor = Class;
     }
     Object.keys(properties).forEach( function(prop) {
           if(prop!=='constructor' && prop!=='extends')
            Class.prototype[prop] = properties[prop];
     });
   return Class; 
}

//Usage
var Car = makeClass({
             constructor: function(name){
                         this.name=name;
                        },
             yourName: function() {
                     return this.name;
                   }
          });
//We have a Car class now
 var carInstance=new Car('Fiat');
carInstance.youName();// ReturnsFiat

var SuperCar = makeClass({
               constructor: function(ignore,power){
                     this.power=power;
                  },
               extends:Car,
               yourPower: function() {
                    return this.power;
                  }
              });
//We have a SuperCar class now, which is subclass of Car
var superCar=new SuperCar('BMW xy',2.6);
superCar.yourName();//Returns BMW xy
superCar.yourPower();// Returns 2.6

선택한 답변에 설명 된대로 전화가 스프레드 연산자와 함께 작동한다고 생각합니다. 내가 빠진 것이 아니라면.
— jhliberty

4

요약:

둘 다 call()에 apply()있는 메소드입니다 Function.prototype. 따라서 프로토 타입 체인을 통해 모든 함수 객체에서 사용할 수 있습니다. 모두 call()와 apply()의 지정된 값의 기능을 실행할 수있다 this.

주요 차이점 call()및 apply()당신이 그것으로 인수를 전달해야하는 방법이다. 모두에서 call()그리고 apply()당신은 첫 번째 인수로이 같은 값으로 할 개체를 전달합니다 this. 다른 주장은 다음과 같이 다릅니다.

  • 로 call()일반적 인수에 넣어 가지고 (두 번째 인수에서 시작)
  • 함께 apply()하면 인수의 배열을 전달해야합니다.

예:

let obj = {
  val1: 5,
  val2: 10
}

const summation = function (val3, val4) {
  return  this.val1 + this.val2 + val3 + val4;
}

console.log(summation.apply(obj, [2 ,3]));
// first we assign we value of this in the first arg
// with apply we have to pass in an array


console.log(summation.call(obj, 2, 3));
// with call we can pass in each arg individually

왜이 기능들을 사용해야합니까?

this값은 자바 스크립트 까다로운 때로는 될 수 있습니다. 함수가 정의 될 때가 아니라 함수가 실행될 때this 결정 되는 값입니다 . 우리의 기능이 올바른 this바인딩 에 의존한다면 우리는 이것을 사용 call()하고 apply()이를 강제 할 수 있습니다 . 예를 들면 다음과 같습니다.

var name = 'unwantedGlobalName';

const obj =  {
  name: 'Willem',
  sayName () { console.log(this.name);}
}


let copiedMethod = obj.sayName;
// we store the function in the copiedmethod variable



copiedMethod();
// this is now window, unwantedGlobalName gets logged

copiedMethod.call(obj);
// we enforce this to be obj, Willem gets logged


4

가장 큰 차이점은 호출을 사용하여 범위를 변경하고 인수를 정상적으로 전달할 수 있지만 apply를 사용하면 인수를 배열로 사용하여 호출 할 수 있습니다 (배열로 전달). 그러나 코드에서 수행 할 작업의 측면에서 보면 매우 비슷합니다.

이 함수의 구문은 apply ()의 구문과 거의 동일하지만 근본적인 차이점은 call ()은 인수 목록을 허용하고 apply ()는 단일 인수 배열을 허용한다는 것입니다.

보시다시피 큰 차이는 없지만 call () 또는 apply ()를 선호하는 경우가 있습니다. 예를 들어 apply 메소드를 사용하여 MDN에서 배열에서 가장 작은 숫자와 가장 큰 숫자를 찾는 아래 코드를 살펴보십시오.

// min/max number in an array
var numbers = [5, 6, 2, 3, 7];

// using Math.min/Math.max apply
var max = Math.max.apply(null, numbers); 
// This about equal to Math.max(numbers[0], ...)
// or Math.max(5, 6, ...)

var min = Math.min.apply(null, numbers)

따라서 주요 차이점은 인수를 전달하는 방식입니다

.

function.call(thisArg, arg1, arg2, ...);

대다:

function.apply(thisArg, [argsArray]);

2

이것에 약간의 세부 사항을 추가하겠습니다.

이 두 통화는 거의 같습니다.

func.call(context, ...args); // pass an array as list with spread operator

func.apply(context, args);   // is same as using apply

사소한 차이가 있습니다.

  • spread운영자는 ... 통과 허용 반복자를 args 호출하는 목록으로.
  • 는 apply단지 허용 어레이 형상 인수한다.

따라서 이러한 호출은 서로를 보완합니다. 우리가 기대하는 경우 반복 가능한 , call우리가 기대하는 작품, 배열과 같은 , apply작품.

실제 배열 처럼 반복 가능 하고 배열과 같은 객체의 경우 기술적으로 사용할 수 있지만 대부분의 JavaScript 엔진이 내부적으로 더 잘 최적화하기 때문에 적용 속도 가 더 빠를 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.