Javascript call () & apply () vs bind ()?


794

난 이미 알고 apply하고 call있는 일련의 유사한 기능이다 this(함수의 컨텍스트).

차이점은 인수를 보내는 방식에 따라 다릅니다 (수동 및 배열)

질문:

그러나 언제 bind()방법을 사용해야 합니까?

var obj = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));

jsbin


9
답변을 게시하거나 투표하기 전에 OP의 평판을 보는 사용자가 있다면 그것은 당신의 잘못이 아닙니다 :)
Gabriel Llamas

54
바인드 가함수를작성하는동안 호출 적용 함수 호출. 당신과 함께인수를 개별적으로 그리고인수 배열로전달하지만. 자세한 내용은 귀하의 질문에 완전히 대답 할 수있는 링크 된 문서를 확인하십시오. call()apply()
Nope

3
kind of weird there is not an existing question about this :그것에 관해서. bind()다른 두 개가 이미 JavaScript 1.8.5-ECMA-262, 5 판에 존재 한 후에 추가 되었기 때문일 수 있습니다. 동안 call()apply()자바 스크립트 1.3부터 주변에있다 - ECMA-262 3 판. 그래서 전화와 적용의 차이점은 무엇입니까 ? 나는 그것을 스스로 궁금하게 생각하면서 만 추측하고 있습니다.
Nope

여기에 이러한 메소드가 필요합니까 (call, apply, bind) ?? 이것이 없으면 메소드를 호출 할 수도 있고 이것은 객체만을 가리킬 것입니다
Mahi

답변:


131

함수 객체, 함수 호출 call/applybind얼마 전에이 비교를 만들었습니다 .

여기에 이미지 설명을 입력하십시오

.bind새 함수 객체를 반환하므로 이후에 함수를 실행할 수 있도록하면서 지금this 값 을 설정할 수 있습니다 .


779

.bind()나중에 특정 상황에서 해당 함수를 호출하여 이벤트에 유용하게 사용할 때 사용하십시오 . 함수를 즉시 호출하고 컨텍스트를 수정하려는 경우 .call()또는을 사용하십시오 .apply().

호출 / 적용은 즉시 함수를 호출하는 반면 bind, 나중에 실행될 때 원래 함수를 호출하기 위해 올바른 컨텍스트를 설정하는 함수를 반환합니다. 이렇게하면 비동기 콜백 및 이벤트에서 컨텍스트를 유지할 수 있습니다.

나는 이것을 많이한다 :

function MyObject(element) {
    this.elm = element;

    element.addEventListener('click', this.onClick.bind(this), false);
};

MyObject.prototype.onClick = function(e) {
     var t=this;  //do something with [t]...
    //without bind the context of this function wouldn't be a MyObject
    //instance as you would normally expect.
};

Node.js에서 광범위하게 사용하여 멤버 메소드를 전달하고 비동기 컨텍스트를 시작한 인스턴스가되도록 비동기 콜백에 사용합니다.

바인드의 단순하고 순진한 구현은 다음과 같습니다.

Function.prototype.bind = function(ctx) {
    var fn = this;
    return function() {
        fn.apply(ctx, arguments);
    };
};

다른 인수를 전달하는 것과 같이 더 많은 것이 있지만 그것에 대해 자세히 읽고 MDN 에서 실제 구현 볼 수 있습니다 .

도움이 되었기를 바랍니다.


2
@RoyiNamir 맞습니다. 나중에 반환 된 "바운드"기능을 사용할 수 있으며 컨텍스트가 유지됩니다.
Chad

5
그것이 정확히 bind돌아 오는 것입니다.
Chad

@RoyiNamir 내 답변 수정
Chad

4
함수가 호출되기 전에 인수를 전달하여 부분에 바인드를 사용할 수도 있습니다.
앤드류 Kirkegaard

1
당신은 바인드를 다시 구현하고 있으며 실제로 차이는 없습니다. 어느 쪽이든 컨텍스트를 보유하는 범위 변수에 액세스 할 수있는 클로저로 랩핑하는 것입니다. 귀하의 코드는 기본적으로 내가 게시 한 폴리 필입니다.
Chad

446

그들은 모두 이것을 함수 (또는 객체)에 첨부 하고 차이점은 함수 호출에 있습니다 (아래 참조).

call은 이것을 함수에 첨부 하고 즉시 함수를 실행합니다.

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

person.hello("world");  // output: "James Smith says hello world"
person.hello.call({ name: "Jim Smith" }, "world"); // output: "Jim Smith says hello world"

bind는 이것을 함수에 첨부하고 다음 과 같이 별도로 호출해야합니다.

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

person.hello("world");  // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world");  // output: Jim Smith says hello world"

또는 이와 같이 :

...    
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc();  // output: Jim Smith says hello world"

apply 는 한 번에 하나씩 인수를 나열하는 대신 배열과 유사한 객체를 사용한다는 점을 제외하고는 호출 과 유사합니다 .

function personContainer() {
  var person = {  
     name: "James Smith",
     hello: function() {
       console.log(this.name + " says hello " + arguments[1]);
     }
  }
  person.hello.apply(person, arguments);
}
personContainer("world", "mars"); // output: "James Smith says hello mars", note: arguments[0] = "world" , arguments[1] = "mars"                                     

1
이것이 바인드가 클로저라는 차이가 있다는 것을 의미합니까?
Gregory R.

코드 스 니펫을 통해 함수 내부에서 사용되는 인수 기능에 대해 방금 가르쳐주었습니다. "use strict"예약 된 키워드를 무시하지 않도록 언급 하는 것이 좋습니다 . +1.
RBT

@Max는 동의했다. 바인드 / 호출 / 적용을 사용할 때까지 "this"가 잘못되었거나 의미가없는 편집을 제출했습니다
iono

1
개선 제안에 감사드립니다. 내 답변을 약간 편집했습니다. @iono 귀하의 제안에 약간의 부정확 한 내용이 있으므로 승인하지 못했지만 답변을 직접 수정했습니다. 바라건대 이제는 더욱 포괄적입니다.
CuriousSuperhero

199

가장 간단한 양식으로 답변

  • 전화는 함수를 호출하고 인수 하나 하나에 전달할 수 있습니다.
  • Apply 는 함수를 호출하고 인수를 배열로 전달할 수 있도록합니다.
  • 바인드 는 새로운 함수를 반환하여이 배열과 여러 인수를 전달할 수 있습니다.

적용 vs. 통화 vs. 바인드 예제

요구

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}

say.call(person1, 'Hello'); // Hello Jon Kuperman
say.call(person2, 'Hello'); // Hello Kelly King

대다

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}

say.apply(person1, ['Hello']); // Hello Jon Kuperman
say.apply(person2, ['Hello']); // Hello Kelly King

묶다

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say() {
    console.log('Hello ' + this.firstName + ' ' + this.lastName);
}

var sayHelloJon = say.bind(person1);
var sayHelloKelly = say.bind(person2);

sayHelloJon(); // Hello Jon Kuperman
sayHelloKelly(); // Hello Kelly King

각각을 사용하는 경우

전화와 신청은 서로 교환이 가능합니다. 배열 또는 쉼표로 구분 된 인수 목록으로 보내는 것이 더 쉬운 지 결정하십시오.

나는 항상 Call이 쉼표 (분리 된 목록)이고 Apply가 배열임을 기억하여 어느 것이 무엇인지 기억합니다.

바인드가 약간 다릅니다. 새로운 함수를 반환합니다. 호출 및 적용은 현재 기능을 즉시 실행합니다.

바인드는 많은 일에 좋습니다. 위의 예와 같이 함수를 카레하는 데 사용할 수 있습니다. 간단한 hello 함수를 helloJon 또는 helloKelly로 바꿀 수 있습니다. 언제 발생하는지 알지 못하지만 원하는 컨텍스트를 알고있는 onClick과 같은 이벤트에도 사용할 수 있습니다.

참조 : codeplanet.io


8
멋진 답변입니다. 내 질문 게시물 인 경우 체크 표시를합니다.
AmerllicA

에서 callapply, 당신이없는 경우 있음에 따라 않는 this방법 안에, 당신은으로 첫 번째 인수를 할당합니다 null?
Daryll Santos

1
MDN에 따르면 @DaryllSantos : thisArg 선택 사항. 이 값은 함수 호출을 위해 제공되었습니다. 이것은 메소드가 보는 실제 값이 아닐 수도 있습니다. 메소드가 엄격하지 않은 모드의 함수 인 경우 null 및 undefined가 전역 오브젝트로 바뀌고 기본 값이 오브젝트로 변환됩니다. 따라서 함수에서 이것을 사용하지 않으면 중요하지 않습니다.
Amit Shah

4
전화 = = 쉼표, 적용 == 배열은 좋은 작은 암기 트릭이었다
drlff

var person1 = {firstName: 'Jon', lastName: 'Kuperman'}; function say(greeting) { console.log(greeting + ' ' + this.firstName + ' ' + this.lastName); } say.apply(person1, ['Hello']); // Hello Jon Kuperman완벽하게 잘 작동하고 출력 VM128 : 4 Hello Jon Kuperman
Pratik

53

this함수의 호출 방식 에 관계 없이 값을 설정할 수 있습니다 . 콜백 작업시 매우 유용합니다.

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(sayHello.bind(obj), 1000);

동일한 결과를 얻으려면 call다음과 같습니다.

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);

5
.bind()이전에 보여 드린 것과 같은 사용법 이 잘못되었습니다. fn.bind(obj)다른 함수 를 사용하면 (이전에 만든 것이 아닌) 반환됩니다. 그리고 함수 this내부의 가치를 바꿀 수있는 능력이 없습니다 binded. 대부분 콜백 this보험에 사용됩니다 . 그러나 귀하의 예에서는 결과에 차이가 없습니다. 그러나 fn !== fn.bind(obj);주목하십시오.
ValeriiVasin

@InviS 귀하의 의견을 이해하지 못합니다-왜 다른 점이 없습니까?
잔 티몬

2
전화와 신청의 차이는 다릅니다. 호출에서 인수를 쉼표로 구분 된 문자열로 전달하는 반면 적용시 배열 형식으로 인수를 전달할 수 있습니다. 나머지는 동일합니다.
Ashish Yadav

쉼표로 구분 된 문자열 ?? 다만 쉼표로 구분 인자를 전달 !
Sudhansu Choudhary

46

multiplication기능이 있다고 가정

function multiplication(a,b){
console.log(a*b);
}

다음을 사용하여 일부 표준 함수를 만들 수 있습니다 bind

var multiby2 = multiplication.bind(this,2);

이제 multiby2 (b)는 곱셈 (2, b)과 같습니다.

multiby2(3); //6
multiby2(4); //8

바인드에서 두 매개 변수를 모두 전달하면 어떻게됩니까?

var getSixAlways = multiplication.bind(this,3,2);

이제 getSixAlways ()는 곱셈 (3,2)과 같습니다.

getSixAlways();//6

심지어 전달 매개 변수는 6을 리턴합니다. getSixAlways(12); //6

var magicMultiplication = multiplication.bind(this);

새로운 곱셈 함수를 만들어 magicMultiplication에 할당합니다.

아뇨, 곱셈 기능을 magicMultiplication에 숨기고 있습니다.

호출 magicMultiplication하면 공백이 반환됩니다.function b()

실행시 잘 작동합니다. magicMultiplication(6,5); //30

전화와 신청은 어떻습니까?

magicMultiplication.call(this,3,2); //6

magicMultiplication.apply(this,[5,2]); //10

간단히 말해서 bind함수를 만들고 함수 callapply실행하는 반면 apply배열의 매개 변수는 기대합니다


잘 설명했다!
CatalinBerta

3
"간단한 단어로 bind함수를 작성하고 함수 callapply실행하는 apply동안 배열의 매개 변수를 기대합니다 "에 대해 +1
Josh Buchea

32

모두 Function.prototype.call()Function.prototype.apply()주어진있는 함수를 호출 this값을, 그 함수의 반환 값을 반환합니다.

Function.prototype.bind()반면에, 주어진 this값 으로 새로운 함수를 만들고, 그 함수를 실행하지 않고 그 함수를 반환합니다.

자, 다음과 같은 함수를 봅시다 :

var logProp = function(prop) {
    console.log(this[prop]);
};

이제 다음과 같은 객체를 보자.

var Obj = {
    x : 5,
    y : 10
};

다음과 같이 함수를 객체에 바인딩 할 수 있습니다.

Obj.log = logProp.bind(Obj);

이제 Obj.log코드의 어느 곳에서나 실행할 수 있습니다.

Obj.log('x'); // Output : 5
Obj.log('y'); // Output : 10

실제로 흥미로운 곳은에 대한 값을 바인딩 할 this뿐만 아니라 인수에 대한 값입니다 prop.

Obj.logX = logProp.bind(Obj, 'x');
Obj.logY = logProp.bind(Obj, 'y');

우리는 이제 이것을 할 수 있습니다 :

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10

23

bind : 제공된 값과 컨텍스트로 함수를 바인딩하지만 함수를 실행하지는 않습니다. 함수를 실행하려면 함수를 호출해야합니다.

call : 제공된 컨텍스트 및 매개 변수를 사용하여 함수를 실행합니다.

apply : 제공된 컨텍스트와 매개 변수를 배열로 사용 하여 함수를 실행합니다 .


간단하고 겸손한!
Habeeb Perwad

18

여기서 하나 개 좋은 문서 사이의 차이를 설명하기 위해 bind(), apply()그리고 call(), 아래로는 요약.

  • bind()함수 나 메소드가 호출 될 때 어떤 특정 객체가 이것에 바인딩 될지를 쉽게 설정할 수 있습니다 .

    // This data variable is a global variable​
    var data = [
        {name:"Samantha", age:12},
        {name:"Alexis", age:14}
    ]
    var user = {
        // local data variable​
        data    :[
            {name:"T. Woods", age:37},
            {name:"P. Mickelson", age:43}
        ],
        showData:function (event) {
            var randomNum = ((Math.random () * 2 | 0) + 1) - 1; // random number between 0 and 1​
            console.log (this.data[randomNum].name + " " + this.data[randomNum].age);
        }
    }
    
    // Assign the showData method of the user object to a variable​
    var showDataVar = user.showData;
    showDataVar (); // Samantha 12 (from the global data array, not from the local data array)​
    /*
    This happens because showDataVar () is executed as a global function and use of this inside 
    showDataVar () is bound to the global scope, which is the window object in browsers.
    */
    
    // Bind the showData method to the user object​
    var showDataVar = user.showData.bind (user);
    // Now the we get the value from the user object because the this keyword is bound to the user object​
    showDataVar (); // P. Mickelson 43​
  • bind() 방법을 빌리 게 해줘

    // Here we have a cars object that does not have a method to print its data to the console​
    var cars = {
        data:[
           {name:"Honda Accord", age:14},
           {name:"Tesla Model S", age:2}
       ]
    }
    
    // We can borrow the showData () method from the user object we defined in the last example.​
    // Here we bind the user.showData method to the cars object we just created.​
    cars.showData = user.showData.bind (cars);
    cars.showData (); // Honda Accord 14​

    이 예제의 한 가지 문제점 showDatacars객체 에 새 메소드 를 추가하고 있으며 , 자동차 오브젝트에 이미 특성 또는 메소드 이름이있을 수 있으므로 메소드를 빌리기 위해이를 수행하고 싶지 않을 수도 있습니다 showData. 우연히 덮어 쓰고 싶지 않습니다. 우리는 우리의 논의에서 볼 수있는 것처럼 ApplyCall아래,이 중 하나를 사용하는 방법 빌려하는 것이 가장 좋습니다 Apply또는 Call방법.

  • bind() 우리가 기능을 카레 할 수 있도록

    부분 함수 응용 프로그램 이라고도하는 함수 Currying 은 이미 설정된 일부 인수와 함께 새 함수를 반환하는 함수 (하나 이상의 인수를 허용하는)를 사용하는 것입니다.

    function greet (gender, age, name) {
        // if a male, use Mr., else use Ms.​
        var salutation = gender === "male" ? "Mr. " : "Ms. ";
        if (age > 25) {
            return "Hello, " + salutation + name + ".";
        }else {
            return "Hey, " + name + ".";
        }
     }

    bind()greet기능 을 카레 하는 데 사용할 수 있습니다

    // So we are passing null because we are not using the "this" keyword in our greet function.
    var greetAnAdultMale = greet.bind (null, "male", 45);
    
    greetAnAdultMale ("John Hartlove"); // "Hello, Mr. John Hartlove."
    
    var greetAYoungster = greet.bind (null, "", 16);
    greetAYoungster ("Alex"); // "Hey, Alex."​
    greetAYoungster ("Emma Waterloo"); // "Hey, Emma Waterloo."
  • apply()또는 call()을 설정

    apply, callbind방법은 모든 방법을 호출 할 때이 값을 설정하는 데 사용됩니다, 그들은 우리의 자바 스크립트 코드의 사용을 직접 제어와 다양성을 허용하는 약간 다른 방법으로 그것을한다.

    apply하고 call는 상기 함수의 매개 변수를 통과 점을 제외하고이 값을 설정하는 경우의 방법은 거의 동일 apply ()같이 배열 하면 할 때, 각각의 매개 변수를 열거 받는 사람에게 전달하는 call ()방법.

    다음은 콜백 함수에서 이것을 사용 call하거나 apply설정 하는 예 입니다.

    // Define an object with some properties and a method​
    // We will later pass the method as a callback function to another function​
    var clientData = {
        id: 094545,
        fullName: "Not Set",
        // setUserName is a method on the clientData object​
        setUserName: function (firstName, lastName)  {
            // this refers to the fullName property in this object​
            this.fullName = firstName + " " + lastName;
        }
    };
    
    function getUserInput (firstName, lastName, callback, callbackObj) {
         // The use of the Apply method below will set the "this" value to callbackObj​
         callback.apply (callbackObj, [firstName, lastName]);
    }
    
    // The clientData object will be used by the Apply method to set the "this" value​
    getUserInput ("Barack", "Obama", clientData.setUserName, clientData);
    // the fullName property on the clientData was correctly set​
    console.log (clientData.fullName); // Barack Obama
  • apply또는로 기능 빌리기call

    • 차용 배열 메소드

      array-like객체를 생성 하고 배열과 유사한 객체에서 작동하는 몇 가지 배열 메소드를 빌려 봅시다 .

      // An array-like object: note the non-negative integers used as keys​
      var anArrayLikeObj = {0:"Martin", 1:78, 2:67, 3:["Letta", "Marieta", "Pauline"], length:4 };
      
       // Make a quick copy and save the results in a real array:
       // First parameter sets the "this" value​
       var newArray = Array.prototype.slice.call (anArrayLikeObj, 0);
       console.log (newArray); // ["Martin", 78, 67, Array[3]]​
      
       // Search for "Martin" in the array-like object​
       console.log (Array.prototype.indexOf.call (anArrayLikeObj, "Martin") === -1 ? false : true); // true​

      또 다른 일반적인 경우는 arguments다음과 같이 배열로 변환 하는 것입니다

        // We do not define the function with any parameters, yet we can get all the arguments passed to it​
       function doSomething () {
          var args = Array.prototype.slice.call (arguments);
          console.log (args);
       }
      
       doSomething ("Water", "Salt", "Glue"); // ["Water", "Salt", "Glue"]
    • 다른 방법을 빌리십시오

      var gameController = {
           scores  :[20, 34, 55, 46, 77],
           avgScore:null,
           players :[
                {name:"Tommy", playerID:987, age:23},
                {name:"Pau", playerID:87, age:33}
           ]
       }
       var appController = {
           scores  :[900, 845, 809, 950],
           avgScore:null,
           avg     :function () {
                   var sumOfScores = this.scores.reduce (function (prev, cur, index, array) {
                        return prev + cur;
               });
               this.avgScore = sumOfScores / this.scores.length;
           }
         }
         // Note that we are using the apply () method, so the 2nd argument has to be an array​
         appController.avg.apply (gameController);
         console.log (gameController.avgScore); // 46.4​
         // appController.avgScore is still null; it was not updated, only gameController.avgScore was updated​
         console.log (appController.avgScore); // null​
  • 가변 -arity 기능 apply()을 실행하는 데 사용

Math.max가변 인수에 대응 함수의 일례

// We can pass any number of arguments to the Math.max () method​
console.log (Math.max (23, 11, 34, 56)); // 56

그러나 전달할 숫자 배열이 있다면 Math.max어떨까요? 우리는 이것을 할 수 없습니다 :

var allNumbers = [23, 11, 34, 56];
// We cannot pass an array of numbers to the the Math.max method like this​
console.log (Math.max (allNumbers)); // NaN

apply ()방법으로 우리가 가변 기능을 실행할 수 있습니다 . 위 대신에 apply ()를 사용하여 숫자 배열을 전달해야합니다 .

var allNumbers = [23, 11, 34, 56];
// Using the apply () method, we can pass the array of numbers:
console.log (Math.max.apply (null, allNumbers)); // 56

8

호출 / 적용 기능을 즉시 실행합니다 :

func.call(context, arguments);
func.apply(context, [argument1,argument2,..]);

bind 는 함수를 즉시 실행하지 않지만 랩핑 된 apply 함수를 반환 합니다 (나중에 실행하기 위해)

function bind(func, context) {
    return function() {
        return func.apply(context, arguments);
    };
}

7

통사론

  • 호출 (thisArg, arg1, arg2, ...)
  • 적용 (thisArg, argsArray)
  • 바인드 (thisArg [, arg1 [, arg2 [, ...]]])

여기

  • thisArg는 객체입니다
  • argArray는 배열 객체입니다
  • arg1, arg2, arg3, ...은 추가 인수입니다.

function printBye(message1, message2){
    console.log(message1 + " " + this.name + " "+ message2);
}

var par01 = { name:"John" };
var msgArray = ["Bye", "Never come again..."];

printBye.call(par01, "Bye", "Never come again...");
//Bye John Never come again...

printBye.call(par01, msgArray);
//Bye,Never come again... John undefined

//so call() doesn't work with array and better with comma seperated parameters 

//printBye.apply(par01, "Bye", "Never come again...");//Error

printBye.apply(par01, msgArray);
//Bye John Never come again...

var func1 = printBye.bind(par01, "Bye", "Never come again...");
func1();//Bye John Never come again...

var func2 = printBye.bind(par01, msgArray);
func2();//Bye,Never come again... John undefined
//so bind() doesn't work with array and better with comma seperated parameters


6

통화, 적용 및 바인드의 기본 차이점은 다음과 같습니다.

실행 컨텍스트가 나중에 그림으로 나오게하려면 바인드가 사용됩니다.

전의:

var car = { 
  registrationNumber: "007",
  brand: "Mercedes",

  displayDetails: function(ownerName){
    console.log(ownerName + ' this is your car ' + '' + this.registrationNumber + " " + this.brand);
  }
}
car.displayDetails('Nishant'); // **Nishant this is your car 007 Mercedes**

다른 변수 에서이 방법을 사용하고 싶다고 가정 해 봅시다.

var car1 = car.displayDetails('Nishant');
car1(); // undefined

다른 변수에서 자동차의 참조를 사용하려면 사용해야합니다

var car1 = car.displayDetails.bind(car, 'Nishant');
car1(); // Nishant this is your car 007 Mercedes

바인드 기능의 더 광범위한 사용에 대해 이야기합시다.

var func = function() {
 console.log(this)
}.bind(1);

func();
// Number: 1

왜? 이제 func은 숫자 1과 바인드되므로이 경우 바인드를 사용하지 않으면 전역 객체를 가리 킵니다.

var func = function() {
 console.log(this)
}.bind({});

func();
// Object

Call, Apply는 명령문을 동시에 실행하려는 경우에 사용됩니다.

var Name = { 
    work: "SSE",
    age: "25"
}

function displayDetails(ownerName) {
    console.log(ownerName + ", this is your name: " + 'age' + this.age + " " + 'work' + this.work);
}
displayDetails.call(Name, 'Nishant')
// Nishant, this is your name: age25 workSSE

In apply we pass the array
displayDetails.call(Name, ['Nishant'])
// Nishant, this is your name: age25 workSSE

4

적용 및 바인딩을 호출하십시오. 그리고 그들이 어떻게 다른지.

일상적인 용어를 사용하여 전화를 배우고 적용 할 수 있습니다.

your_scooter , your_car and your_jet동일한 메커니즘 (방법)으로 시작하는 3 개의 자동차 가 있습니다. automobile메소드를 사용 하여 객체 를 만들었습니다 push_button_engineStart.

var your_scooter, your_car, your_jet;
var automobile = {
        push_button_engineStart: function (runtime){
        console.log(this.name + "'s" + ' engine_started, buckle up for the ride for ' + runtime + " minutes");
    }
}

언제 전화를 걸고 적용하는지 알 수 있습니다. 당신이 엔지니어이고, 당신이 가지고 있다고 가정하자 your_scooter, your_car하고 your_jet있는이 push_button_engine_start와 함께 제공되지 않은 당신이 제 3자를 사용하고자하는 push_button_engineStart.

다음 코드 줄을 실행하면 오류가 발생합니다. 왜?

//your_scooter.push_button_engineStart();
//your_car.push_button_engineStart();
//your_jet.push_button_engineStart();


automobile.push_button_engineStart.apply(your_scooter,[20]);
automobile.push_button_engineStart.call(your_jet,10);
automobile.push_button_engineStart.call(your_car,40);

위의 예는 your_scooter, your_car, your_jet에 자동차 오브젝트의 기능을 성공적으로 제공합니다.

더 깊이 들어가 보자 여기서는 위의 코드 줄을 나눕니다. automobile.push_button_engineStart우리가 사용되는 방법을 얻도록 돕고 있습니다.

또한 점 표기법을 사용하여 apply 또는 call을 사용합니다. automobile.push_button_engineStart.apply()

이제 두 개의 매개 변수를 적용하고 호출하십시오.

  1. 문맥
  2. 인수

여기에서 코드의 마지막 줄에 컨텍스트를 설정합니다.

automobile.push_button_engineStart.apply(your_scooter,[20])

call과 apply의 차이점은 apply 는 배열 형식의 매개 변수를 받아들이고 call은 단순히 쉼표로 구분 된 인수 목록을 받아 들일 수 있다는 것입니다.

JS 바인드 기능이란 무엇입니까?

바인드 함수는 기본적으로 무언가의 컨텍스트를 바인드 한 후 나중에 실행할 수 있도록 변수에 저장합니다.

이전 예제를 더 좋게 만들어 봅시다. 앞서 우리는 자동차 객체에 속하는 방법을 사용하여 장비를 사용했습니다 your_car, your_jet and your_scooter. 이제 우리가 원하는 push_button_engineStart실행 후반에 개별적으로 자동차를 시동 하기 위해 별도의 별개 를 제공하고 싶다고 상상해보십시오 .

var scooty_engineStart = automobile.push_button_engineStart.bind(your_scooter);
var car_engineStart = automobile.push_button_engineStart.bind(your_car);
var jet_engineStart = automobile.push_button_engineStart.bind(your_jet);


setTimeout(scooty_engineStart,5000,30);
setTimeout(car_engineStart,10000,40);
setTimeout(jet_engineStart,15000,5);

여전히 만족하지 않습니까?

눈물 방울로 명확하게합시다. 실험 할 시간. 함수 응용 프로그램을 호출하여 적용한 다음 함수 값을 참조로 저장해 보겠습니다.

아래의 실험은 호출 및 적용이 즉시 호출되기 때문에 실패하므로 바인드 함수가 쇼를 훔치는 변수에 참조를 저장하는 단계에 결코 도달하지 않습니다.

var test_function = automobile.push_button_engineStart.apply(your_scooter);


3

호출 : 호출은 함수를 호출하고 인수를 하나씩 전달할 수 있도록합니다.

적용 : 적용은 함수를 호출하고 인수를 배열로 전달할 수 있도록합니다.

바인드 : 바인드는 새 함수를 리턴하여이 배열과 여러 인수를 전달할 수 있습니다.

var person1 = {firstName: 'Raju', lastName: 'king'};
var person2 = {firstName: 'chandu', lastName: 'shekar'};

function greet(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}
function greet2(greeting) {
        console.log( 'Hello ' + this.firstName + ' ' + this.lastName);
    }


greet.call(person1, 'Hello'); // Hello Raju king
greet.call(person2, 'Hello'); // Hello chandu shekar



greet.apply(person1, ['Hello']); // Hello Raju king
greet.apply(person2, ['Hello']); // Hello chandu shekar

var greetRaju = greet2.bind(person1);
var greetChandu = greet2.bind(person2);

greetRaju(); // Hello Raju king
greetChandu(); // Hello chandu shekar


2

call () :- 여기서 배열 형식이 아닌 함수 인수를 개별적으로 전달합니다.

var obj = {name: "Raushan"};

var greeting = function(a,b,c) {
    return "Welcome "+ this.name + " to "+ a + " " + b + " in " + c;
};

console.log(greeting.call(obj, "USA", "INDIA", "ASIA"));

apply () :- 여기서 함수 인수를 배열 형식으로 전달합니다.

var obj = {name: "Raushan"};

var cal = function(a,b,c) {
    return this.name +" you got " + a+b+c;
};

var arr =[1,2,3];  // array format for function arguments
console.log(cal.apply(obj, arr)); 

bind () :-

       var obj = {name: "Raushan"};

       var cal = function(a,b,c) {
            return this.name +" you got " + a+b+c;
       };

       var calc = cal.bind(obj);
       console.log(calc(2,3,4));

2

자바 스크립트 호출 ()

const person = {
    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.call(anotherPerson,1,2)

자바 스크립트 적용 ()

    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.apply(anotherPerson,[1,2])

** 호출 및 적용 함수는 별도의 인수를 사용하는 차이 호출이지만 다음과 같이 배열을 적용합니다. [1,2,3] **

자바 스크립트 바인드 ()

    name: "Lokamn",
    dob: 12,
    anotherPerson: {
        name: "Pappu",
        dob: 12,
        print2: function () {
            console.log(this)
        }
    }
}

var bindFunction = person.anotherPerson.print2.bind(person)
 bindFunction()

1

바인드를 사용할 수 없다고 상상하십시오. 다음과 같이 쉽게 구성 할 수 있습니다.

var someFunction=...
var objToBind=....

var bindHelper =  function (someFunction, objToBind) {
    return function() {
        someFunction.apply( objToBind, arguments );
    };  
}

bindHelper(arguments);

1
    function sayHello() {
            //alert(this.message);
            return this.message;
    }
    var obj = {
            message: "Hello"
    };

    function x(country) {
            var z = sayHello.bind(obj);
            setTimeout(y = function(w) {
//'this' reference not lost
                    return z() + ' ' + country + ' ' + w;
            }, 1000);
            return y;
    }
    var t = x('India')('World');
    document.getElementById("demo").innerHTML = t;

0

이 모든 방법의 기본 개념은 기능 차용 입니다.

함수 차용을 사용하면 해당 메소드의 사본을 작성하지 않고 별도의 두 위치에 유지할 필요없이 한 오브젝트의 메소드를 다른 오브젝트에서 사용할 수 있습니다. 의 사용을 통해 달성됩니다. call (),. apply () 또는. bind (), 우리가 빌린 메소드에서 명시 적으로 설정하기 위해 존재합니다.

  1. 호출 은 즉시 함수를 호출하고 인수를 하나씩 전달할 수 있도록합니다.
  2. Apply 는 즉시 함수를 호출하고 인수를 배열 로 전달할 수 있습니다 .
  3. 바인드 는 새 함수를 반환하며 함수를 호출하여 언제든지 호출하거나 호출 할 수 있습니다.

아래는이 모든 방법의 예입니다

let name =  {
    firstname : "Arham",
    lastname : "Chowdhury",
}
printFullName =  function(hometown,company){
    console.log(this.firstname + " " + this.lastname +", " + hometown + ", " + company)
}

요구

첫 번째 인수, 예를 들어 call 메소드의 이름은 항상 (this) 변수에 대한 참조이며 후자는 함수 변수입니다.

printFullName.call(name,"Mumbai","Taufa");     //Arham Chowdhury, Mumbai, Taufa

대다

apply 메소드는 call 메소드와 동일하지만 유일한 차이점은 함수 인수가 Array 목록에 전달된다는 것입니다.

printFullName.apply(name, ["Mumbai","Taufa"]);     //Arham Chowdhury, Mumbai, Taufa

묶다

bind 메소드는 호출과 동일하지만 bind는 호출하여 나중에 사용할 수있는 함수를 리턴합니다 (즉시 호출하지는 않음).

let printMyNAme = printFullName.bind(name,"Mumbai","Taufa");

printMyNAme();      //Arham Chowdhury, Mumbai, Taufa

printMyNAme ()은 함수를 호출하는 함수입니다.

아래는 jsfiddle에 대한 링크입니다

https://codepen.io/Arham11/pen/vYNqExp


-1

나는 그것들의 동일한 장소가 있다고 생각합니다 : 그들 모두 함수 의이 값을 변경할 수 있습니다. 차이점은 다음과 같습니다 : bind 함수는 새로운 함수를 결과로 반환합니다. call 및 apply 메소드는 함수를 즉시 실행하지만 apply는 배열을 params로 받아들이고 배열을 분리하여 구문 분석하며 bind 함수는 Currying이 될 수 있습니다.


-3

예를 들어, 특정 컨텍스트를 가진 함수를 할당하고자 할 때 bind 함수를 사용해야합니다.

var demo = {
           getValue : function(){ 
             console.log('demo object get value       function') 
            }
           setValue : function(){  
              setTimeout(this.getValue.bind(this),1000)           
           }
 }

위의 예제에서 demo.setValue () 함수를 호출하고 this.getValue 함수를 직접 전달하면 setTimeout의이 객체가 창 객체를 참조하므로 데모 객체 컨텍스트를 this.getValue에 전달해야하므로 demo.setValue 함수를 직접 호출하지 않습니다. 바인드를 사용하는 함수. 그것은 실제로 함수를 호출하지 않는 데모 객체의 컨텍스트에서만 함수를 전달한다는 것을 의미합니다.

당신이 이해 바랍니다.

자세한 내용은 javascript 바인드 함수 를 참조하십시오.

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