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


794

私はすでにそれを知ってapplyおり、call設定する同様の関数ですthis(関数のコンテキスト)。

違いは、引数の送信方法(手動vs配列)です。

質問:

しかし、いつ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
ユーザーが答えかupvotingを投稿する前にOPの評判ポイントを見て:)ことがある場合、それはあなたのせいではありません
ガブリエル・ラマ

54
bindが関数を作成する間、 callおよび applyは関数を呼び出します。ただし、引数は個別に、引数配列として渡します。詳細については、質問に完全に回答できるはずのリンクされたドキュメントを確認してください。call()apply()
2013年

3
kind of weird there is not an existing question about this :それについて。それはおそらくbind()、他の2つがすでにJavaScript 1.8.5-ECMA-262、第5版に存在していた後に追加されたためです。しばらくcall()してapply()JavaScriptの1.3以来の周りされている- ECMA-262第3版。SOには次のような質問があります:what-is-the-difference-between-call-and-apply。私はそれを自分自身で疑問に思っていたので、私は推測しているだけです。
2013年

ここにこれらのメソッド(呼び出し、適用、バインド)が必要ですか?これがなければ、メソッドを呼び出すこともでき、これはオブジェクトのみを指します
Mahi

-リンクチェックアウトtechyaura-blogs.blogspot.com/2020/05/...
techyaura

回答:


131

関数オブジェクト、関数呼び出し、call/applyおよびbindしばらく前にこの比較を作成しました:

ここに画像の説明を入力してください

.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でメンバーメソッドを渡したい非同期コールバックに幅広く使用していますが、非同期アクションを開始したインスタンスをコンテキストにする必要があります。

bindの単純で素朴な実装は次のようになります。

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

(他の引数を渡すのと同じように)それにはもっとありますが、それについてもっと読んでMDNの実際の実装を見ることができます。

お役に立てれば。


2
正しい@RoyiNamir、後で返された「bound」関数を使用でき、コンテキストは維持されます。
チャド

5
それがまさにbind戻ります。
チャド

@RoyiNamirが私の回答を編集
チャド

4
関数を呼び出す前に引数を渡して、パーシャルにバインドを使用することもできます。
Andrew Kirkegaard 2013年

1
バインドを再実装しているだけで、実際には違いはありません。どちらの方法でも、コンテキストを保持するスコープ変数にアクセスできるクロージャーにラップするだけです。あなたのコードは基本的に私が投稿したポリフィルです。
2014年

446

それらはすべてこれを関数(またはオブジェクト)にアタッチし、違いは関数の呼び出しにあります(以下を参照)。

呼び出しはこれを関数にアタッチし、関数をすぐに実行します。

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"

applycallに似ていますが、引数を1つずつリストするのではなく、配列のようなオブジェクトをとります。

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
これは、Bindがクロージャーであることの違いを意味しますか?
グレゴリーR.

コードスニペットを通じて関数内で使用される引数機能について教えてくれました。この"use strict"ような予約済みキーワードを上書きしないように言及することをお勧めします。+1。
RBT

@Maxは同意しました。bind / call / applyを使用するまで「this」が間違っているか意味がない編集を提出しました
iono

1
改善提案をありがとう。回答を少し編集しました。@ionoあなたの提案には不正確な点があったため、承認できませんでしたが、答えを自分で編集しました。うまくいけば、より包括的になりました。
好奇心が強いスーパーヒーロー2017年

200

SIMPLEST形式で回答

  • コールは関数を呼び出し、引数を1つずつ渡すことができます。
  • Applyは関数を呼び出し、引数を配列として渡すことができます。
  • Bindは新しい関数を返し、this配列と任意の数の引数を渡すことができます。

適用、呼び出し、バインドの例

コール

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は配列用であることを覚えておくことで、どちらがどれかを常に覚えています。

バインドは少し異なります。新しい関数を返します。呼び出しと適用は、現在の関数をすぐに実行します。

Bindは多くのことに適しています。上記の例のように、関数をカレーするために使用できます。単純なhello関数を取得して、helloJonまたはhelloKellyに変換できます。onClickのようなイベントがいつ発生するかはわかりませんが、どのようなコンテキストにするかはわかっているイベントにも使用できます。

リファレンス:codeplanet.io


8
すばらしい回答です。それが私の質問投稿だった場合は、チェックマークを付けます。
AmerllicA 2017

ではcallapply、あなたが持っていない場合ということにはないthisメソッドの内部で、その後、あなたに最初の引数を割り当てるでしょうかnull
ダリルサントス

1
@ DaryllSantos、MDNによると:thisArgオプション。関数の呼び出しに提供されるこの値。これは、メソッドによって表示される実際の値ではない可能性があることに注意してください。メソッドが非厳密モードの関数である場合、nullおよびundefinedはグローバルオブジェクトに置き換えられ、プリミティブ値はオブジェクトに変換されます。したがって、関数でこれを使用しなくても問題ありません。
アミットシャー

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)他の関数を使用すると、返されます(以前に作成したものではありません)。またthisbinded関数内の値を変更する機能はありません。ほとんどの場合、これはコールバックthis保険に使用されます。しかし、あなたの例では-結果に違いはありません。しかし、それにfn !== fn.bind(obj);注意してください。
ValeriiVasin 2013年

@InviS私はあなたのコメントを理解できません-なぜ違いがないのですか?
jantimon 2015

2
呼び出しと適用の違いはです。呼び出しではコンマ区切りの文字列として引数を渡しますが、適用では配列の形式で引数を渡すことができます。残りは同じです。
アシシュヤダフ2017

カンマ区切りの文字列 ?? 引数をカンマ区切りで渡すだけです !!
Sudhansu Choudhary

46

multiplication関数があると仮定します

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

を使用していくつかの標準関数を作成してみましょう bind

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

これでmultiby2(b)はmultiplication(2、b)と等しくなります。

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

bindで両方のパラメーターを渡した場合

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

現在getSixAlways()はmultiplication(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に言うcallと、関数を作成して関数をapply実行applyしますが、配列のパラメーターを期待します


とてもよく説明されました!
CatalinBerta 2016

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​

    この例の問題の1つはshowDatacarsオブジェクトに新しいメソッドを追加することです。carsオブジェクトには既にプロパティまたはメソッド名がある可能性があるため、メソッドを借用するためにそれを実行したくない場合がありますshowData。誤って上書きしたくない。私たちは私たちの議論で見るようにApplyし、Call下に、それはどちらかの使用方法借りるのがベストであるApplyCallの方法を。

  • bind() 関数をカレーできるようにする

    関数カリー化は部分関数適用とも呼ばれ、一部の引数が既に設定された新しい関数を返す関数(1つ以上の引数を受け入れる)の使用です。

    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()を設定する

    applycallbind方法は、すべてのメソッドを呼び出すときに、この値を設定するために使用されている、と彼らは私たちのJavaScriptコードで使用する直接制御と汎用性を可能にするために、わずかに異なる方法でそれを行います。

    applyそしてcallあなたは、関数のパラメータを渡すことを除いて、この値を設定するときの方法はほとんど同じですapply ()として配列あなたがする必要がある一方で、個別のパラメータをリストにそれらを渡すためにcall ()方法。

    これは、コールバック関数で使用callまたはapply設定する1つの例です。

    // 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​
  • 可変アリティ関数の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

call / applyは関数をすぐに実行します:

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

bindは関数をすぐには実行しませんが、ラップれた適用関数を返します(後で実行するため):

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

Call、Apply、Bindの基本的な違いは次のとおりです。

バインドは、実行コンテキストを後から追加したい場合に使用されます。

例:

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

applyとbindを呼び出します。そしてそれらがどのように違うのか。

日常の用語を使って電話と申し込みを学びましょう。

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_scooteryour_carそしてyour_jetどのpush_button_engine_startで来て、あなたが第三者の使用を希望しませんでした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オブジェクトの機能を正常に提供します。

さらに詳しく見てみましょう ここで、上記のコード行を分割します。 automobile.push_button_engineStart使用されているメソッドを取得するのに役立ちます。

さらに、ドット表記を使用して、applyまたはcallを使用します。 automobile.push_button_engineStart.apply()

次に、2つのパラメーターを適用して呼び出します。

  1. 環境
  2. 引数

したがって、ここではコードの最終行にコンテキストを設定します。

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

呼び出しと適用の違いが配列の形式のパラメーターを受け入れることだけですが、callはコンマで区切られた引数のリストを受け入れるだけです。

JS Bind関数とは何ですか?

バインド関数は基本的に何かのコンテキストをバインドし、それを後で実行するために変数に格納します。

前の例をさらに良くしましょう。以前は、automobileオブジェクトに属するメソッドを使用して、それを装備していました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

Call: callは関数を呼び出し、引数を1つずつ渡すことができます

適用:適用は関数を呼び出し、引数を配列として渡すことができます

バインド:バインドは新しい関数を返し、this配列と任意の数の引数を渡すことができます。

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)); 

練る() : -

       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

JavaScript Call()

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)

JavaScriptのapply()

    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])

** call関数とapply関数は別の引数を取りますが、apply take配列は次のようになります。

JavaScript bind()

    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

このすべてのメソッドの背後にある主な概念は、関数のバローイングです。

関数の借用により、1つのオブジェクトのメソッドを別のオブジェクトで使用でき、そのメソッドのコピーを作成して2つの別々の場所で維持する必要はありません。これは、を使用して実現されます。call()、。apply()、または。bind()、これらはすべて、借りているメソッドでこれを明示的に設定するために存在します

  1. 呼び出しはすぐに関数を呼び出し、引数を1つずつ渡すことができます
  2. Applyは関数をすぐに呼び出し、引数を配列として渡すことができます。
  3. Bindは新しい関数を返し、関数を呼び出すことにより、いつでも好きなときにそれを呼び出すことができます。

以下は、このすべてのメソッドの例です

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

コール

最初の引数、たとえば呼び出しメソッド内の名前は常に(this)変数への参照であり、後者は関数変数になります

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

適用する

applyメソッドはcallメソッドと同じですが、唯一の違いは、関数の引数が配列リストで渡されることです。

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

練る

bindメソッドはcallと同じですが、bindは後で呼び出すことで使用できる関数を返します(すぐには呼び出されません)。

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

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

printMyNAme()は、関数を呼び出す関数です

以下はjsfiddleのリンクです

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


-1

同じ場所だと思います:それらはすべて関数のthis値を変更できます。それらの違いは次のとおりです:バインド関数は結果として新しい関数を返します。callメソッドとapplyメソッドは関数をすぐに実行しますが、applyは配列をパラメーターとして受け入れることができ、分離された配列を解析します。また、バインド関数は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関数を直接渡すと、demo.setValue関数は直接呼び出されません。これは、setTimeoutのこれがウィンドウオブジェクトを参照するため、デモオブジェクトコンテキストをthis.getValueに渡す必要があるためです。 bindを使用する関数。これは、関数を実際に呼び出すのではなく、デモオブジェクトのコンテキストでのみ関数を渡すことを意味します。

理解してほしい。

詳細については、javascript bind functionを参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.