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


3103

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

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 모두 callapply두 개의 매개 변수를 사용합니다. 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.addValuesf동일한 기능을 참조하십시오, 그들은 수신기의 값이 각 통화에서 다르기 때문에 전화했을 때 다르게 동작합니다. 따라서을 참조하는 함수를 호출 할 때 호출 될 때 올바른 값 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전역 개체에 이름이 지정된 속성을 추가 할 때와 동일한 바람직하지 않은 부작용이 있습니다.

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


추출물의 끝.


사실 additionalValuesobj.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');

hellosayHello사용하여 얼마나 쉽게 위임했는지 관찰하십시오 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.