JavaScriptの「バインド」メソッドの用途は何ですか?


651

bind()JavaScriptでの使用は何ですか?


8
私の標準的な使用例:select = document.querySelector.bind(document)
2017

1
^そして、疑問に思う方のために、必要なのは、グローバルオブジェクトであるをthis参照するためwindowです。ではdocument.querySelector.bind(document)、がを指すのであって、を指すselectのでthisdocumentないことを確認しwindowます。私がそれを誤解した場合、誰かが私を訂正します。
AleksandrH

回答:


614

Bindは、関数のthis内部をに渡されるパラメーターにするための新しい関数を作成しbind()ます。

bindこれは、正しいを使用してメンバーメソッドを渡す方法を示す例ですthis

var myButton = {
  content: 'OK',
  click() {
    console.log(this.content + ' clicked');
  }
};

myButton.click();

var looseClick = myButton.click;
looseClick(); // not bound, 'this' is not myButton - it is the globalThis

var boundClick = myButton.click.bind(myButton);
boundClick(); // bound, 'this' is myButton

どちらが出力されるか:

OK clicked
undefined clicked
OK clicked

最初の(this)パラメーターの後にパラメーターを追加してbind、それらの値を元の関数に渡すこともできます。バインドされた関数に後で渡す追加のパラメーターは、バインドされたパラメーターの後に渡されます。

// Example showing binding some parameters
var sum = function(a, b) {
  return a + b;
};

var add5 = sum.bind(null, 5);
console.log(add5(10));

どちらが出力されるか:

15

詳細とインタラクティブな例については、JavaScript関数バインドを確認してください。

更新:ECMAScript 2015は=>関数のサポートを追加します。 =>関数はよりコンパクトであり、thisポインターをその定義スコープから変更しないためbind()、頻繁に使用する必要がない場合があります。たとえばButton、最初の例の関数をオンにしてclickコールバックをDOMイベントにフックしたい場合、次の方法はすべて有効な方法です。

var myButton = {
  ... // As above
  hookEvent(element) {
    // Use bind() to ensure 'this' is the 'this' inside click()
    element.addEventListener('click', this.click.bind(this));
  }
};

または:

var myButton = {
  ... // As above
  hookEvent(element) {
    // Use a new variable for 'this' since 'this' inside the function
    // will not be the 'this' inside hookEvent()
    var me = this;
    element.addEventListener('click', function() { me.click() });
  }
};    

または:

var myButton = {
  ... // As above
  hookEvent(element) {
    // => functions do not change 'this', so you can use it directly
    element.addEventListener('click', () => this.click());
  }
};

6
優れた外植ですが、最初の選択肢の代わりに、あなたが説明した3番目の選択肢を使用したい例を見つけるのに苦労しています。3番目のオプションを使用する必要性を感じた状況を説明できますか?
ダリル

5
'this'のバインド以外にbindを使用したことはないと思います。もう1つの形式は部分アプリケーションと呼ばれ、関数型言語ではかなり一般的です。完全を期すために含まれていると思います。
nkron、2015年

43
looseClick()がmyButtonにバインドされない理由を誰かが疑問に思っている場合、これは「this」が関数(looseClick())を呼び出すオブジェクトを参照しているためです。looseClick()を呼び出すオブジェクトは、グローバルオブジェクトです。
pokero 2015

4
@Darryl-イベントハンドラーからパラメーターを渡す必要がある理由の1つ。この反応コードがある場合:var Note = React.createClass({ add: function(text){ ... }, render: function () { return <button onClick={this.add.bind(null, "New Note")}/> } }ボタンをクリックすると、addメソッドにパラメーターテキスト「New Note」が渡されます。
P.マイヤーノア2016

2
「最初のパラメーターの後に追加のパラメーターを追加することもできます。バインドは、バインドされた関数に渡す追加のパラメーターを渡す前に、それらの値を元の関数に渡します。」この表現は混乱を招きます。
ケンイングラム

271

の最も簡単な使用法はbind()、どのように呼び出されても、特定のthis値で呼び出される関数を作成することです。

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

module.getX(); // 81

var getX = module.getX;
getX(); // 9, because in this case, "this" refers to the global object

// create a new function with 'this' bound to module
var boundGetX = getX.bind(module);
boundGetX(); // 81

詳細については、このリンクを参照してください

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind


38
bind()のこれまでで最高の紹介。
thomasfl

3
あなたの例はprototype初心者にとって新しいかもしれない言語機能(例えば)についての知識を必要としないので、素晴らしい答えです。
Edward

1
簡潔で非常に明確です!
パピギー

172

バインド許可

  • 「this」の値を特定のオブジェクトに設定します。これは時々これとして非常に役立ちますが意図したものと異なるは。
  • 再利用方法
  • 関数をカレーします

たとえば、クラブの月額料金を差し引く機能があります。

function getMonthlyFee(fee){
  var remaining = this.total - fee;
  this.total = remaining;
  return this.name +' remaining balance:'+remaining;
}

次に、この機能を別のクラブ会員に再利用したいとします。月額料金は会員ごとに異なりますのでご注意ください。

レイチェルの残高が500で、月額会費が90であるとしましょう。

var rachel = {name:'Rachel Green', total:500};

今、毎月彼女のアカウントから手数料を差し引くために何度も使用できる関数を作成します

//bind
var getRachelFee = getMonthlyFee.bind(rachel, 90);
//deduct
getRachelFee();//Rachel Green remaining balance:410
getRachelFee();//Rachel Green remaining balance:320

これで、同じgetMonthlyFee関数を、会費が異なる別のメンバーに使用できます。たとえば、Ross Gellerの残高は250、月額料金は25です。

var ross = {name:'Ross Geller', total:250};
//bind
var getRossFee = getMonthlyFee.bind(ross, 25);
//deduct
getRossFee(); //Ross Geller remaining balance:225
getRossFee(); //Ross Geller remaining balance:200

9
あなたの例では、各メンバーが独自のプロパティ/メソッドを持つ新しいキーワードでインスタンス化されたメンバーオブジェクトをセットアップする傾向があると思います。次に、それは単にross.getMonthlyFee(25)の問題です。この例は、単にbind()の使用を示すためのものでしたか、それとも、あなたのアプローチにいくつかの利点がありますか?
ダリル

カレーの機能が大好き!
Jerry Liu

わかりませんが、var getRachelFee = getMonthlyFee(rachel、90);を実行します。そして、関数は関数に沿った関数getMonthlyFee(member、fee){}になります。
ミゲル

1
@KhanSharp正解ですが、TVシリーズの友達への言及により、コメントと賛成が得られます。answerとお答えいただきありがとうございます。
Saurabh Lende

79

以下からのMDNドキュメントFunction.prototype.bind()

バインド()メソッドが呼び出され、という新たな機能を作成し、新しい関数が呼び出されたときに提供される任意の前の引数の指定された配列と与えられた値に対するこのキーワードセットを有しています。

だから、それはどういう意味ですか?

さて、次のような関数を見てみましょう:

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オブジェクトにバインドしているため、これは機能しますObj


本当に興味深いのは、の値をバインドするだけthisでなく、その引数もバインドするときですprop

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

これを行うことができます:

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

とは異なり、バインディングを行うときにこれらの値を渡したため、またはObj.logを渡すx必要はありませんy


9
この答えはもっと愛を得るはずです。よく説明しました。
Chax 2016

一般的な概要と具体的な例の非常に良い組み合わせ。
ケンイングラム

100アップを真っ直ぐ撃つボタンはどこにあるの?
kushalvm 2017年

これにより、バインドされた「null」の使用を理解するために、部分的に適用された関数の MDNドキュメントセクションを読むことをお勧めします。ほとんどのバインド使用では、ゲートを閉じます。 developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
kushalvm

23

変数には、ローカルスコープとグローバルスコープがあります。同じ名前の2つの変数があるとします。1つはグローバルに定義され、もう1つは関数クロージャ内で定義されており、関数クロージャ内にある変数値を取得したいと考えています。その場合、このbind()メソッドを使用します。以下の簡単な例をご覧ください。

var x = 9; // this refers to global "window" object here in the browser
var person = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

var y = person.getX; // It will return 9, because it will call global value of x(var x=9).

var x2 = y.bind(person); // It will return 81, because it will call local value of x, which is defined in the object called person(x=81).

document.getElementById("demo1").innerHTML = y();
document.getElementById("demo2").innerHTML = x2();
<p id="demo1">0</p>
<p id="demo2">0</p>


18

概要:

このbind()メソッドは、オブジェクトを最初の引数として取り、新しい関数を作成します。関数が呼び出されるthisと、関数本体の値は、引数として渡されたオブジェクトになります。bind()ます。

どうやって thisとにかくJSでますか

thisJavaScript のの値は、常に、関数が呼び出されるオブジェクトによって異なります。この値は常にドットの左側のオブジェクトを参照しますここで、関数は呼び出されます。グローバルスコープの場合、これはwindow(またはglobalnodeJS)です。のみcallapplyおよびbindこのバインディングを異なる方法で変更できます。thisキーワードの仕組みを示す例を次に示します。

let obj = {
  prop1: 1,
  func: function () { console.log(this); } 
}

obj.func();   // obj left of the dot so this refers to obj

const customFunc = obj.func;  // we store the function in the customFunc obj

customFunc();  // now the object left of the dot is window, 
               // customFunc() is shorthand for window.customFunc()
               // Therefore window will be logged

バインドはどのように使用されますか?

バインドは、参照this先のオブジェクトを固定することで、キーワードの問題を解決するのに役立ちますthis。例えば:

var name = 'globalName';

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

const say = obj.sayName; // we are merely storing the function the value of this isn't magically transferred

say(); // now because this function is executed in global scope this will refer to the global var

const boundSay = obj.sayName.bind(obj); // now the value of this is bound to the obj object

boundSay();  // Now this will refer to the name in the obj object: 'myName'

関数が特定のthis値にバインドされると、それを渡したり、他のオブジェクトのプロパティに配置したりできます。の値はthis変わりません。


3
あなたのコード内のあなたのご意見は、objそれがドットの左側とされているので、オブジェクトであるwindow、それはのための短縮形であるため、オブジェクトであるwindow.custFunc()window私にとって非常に洞察に満ちたドットの残っています。
nzaleski 2018年

12

理論的にも実際的にもバインドを説明します

javascriptのbindはメソッドです-Function.prototype.bind。bindはメソッドです。関数プロトタイプで呼び出されます。このメソッドは、その本体が呼び出される関数に類似した関数を作成しますが、「this」はbindメソッドに渡される最初のパラメーターを参照します。その構文は

     var bindedFunc = Func.bind(thisObj,optionsArg1,optionalArg2,optionalArg3,...);

例:-

  var checkRange = function(value){
      if(typeof value !== "number"){
              return false;
      }
      else {
         return value >= this.minimum && value <= this.maximum;
      }
  }

  var range = {minimum:10,maximum:20};

  var boundedFunc = checkRange.bind(range); //bounded Function. this refers to range
  var result = boundedFunc(15); //passing value
  console.log(result) // will give true;

基本的には、関数内の「this」を、渡したオブジェクトにしますよね?
Harvey Lin

11

bind()メソッドは、この値がbind()に渡された値にバインドされている新しい関数インスタンスを作成します。例えば:

   window.color = "red"; 
   var o = { color: "blue" }; 
   function sayColor(){ 
       alert(this.color); 
   } 
   var objectSayColor = sayColor.bind(o); 
   objectSayColor(); //blue 

ここでは、bind()を呼び出してオブジェクトoを渡すことにより、sayColor()からobjectSayColor()という新しい関数が作成されます。objectSayColor()関数のthis値はoと同じであるため、この関数を呼び出すと、グローバルコールとしても、文字列「blue」が表示されます。

参照:Nicholas C. Zakas-ウェブ開発者向けのプロフェッショナルJAVASCRIPT®


簡潔で簡潔な例
アフマドシャリフ

9

引数を値にバインドして新しい関数を作成する

このbindメソッドは、暗黙のthis引数を含め、1つ以上の引数が特定の値にバインドされた別の関数から新しい関数を作成します。

部分的なアプリケーション

これは部分的な適用のです。通常、値を生成するすべての引数を持つ関数を提供します。これは関数適用と呼ばれます。関数を引数に適用しています。

高次関数(HOF)

部分的なアプリケーションは、引数の数が少ない新しい関数を生成するため、高次関数(HOF)の例です

複数の引数のバインド

を使用bindして、複数の引数を持つ関数を新しい関数に変換できます。

function multiply(x, y) { 
    return x * y; 
}

let multiplyBy10 = multiply.bind(null, 10);
console.log(multiplyBy10(5));

インスタンスメソッドから静的関数への変換

最も一般的な使用例では、1つの引数で呼び出されると、bindメソッドはthis特定の値にバインドされた値を持つ新しい関数を作成します。実際には、これによりインスタンスメソッドが静的メソッドに変換されます。

function Multiplier(factor) { 
    this.factor = factor;
}

Multiplier.prototype.multiply = function(x) { 
    return this.factor * x; 
}

function ApplyFunction(func, value) {
    return func(value);
}

var mul = new Multiplier(5);

// Produces garbage (NaN) because multiplying "undefined" by 10
console.log(ApplyFunction(mul.multiply, 10));

// Produces expected result: 50
console.log(ApplyFunction(mul.multiply.bind(mul), 10));

ステートフルコールバックの実装

次の例は、バインディングを使用してthis、オブジェクトのメソッドを、オブジェクトの状態を簡単に更新できるコールバックとして機能させる方法を示しています。

function ButtonPressedLogger()
{
   this.count = 0;
   this.onPressed = function() {
      this.count++;
      console.log("pressed a button " + this.count + " times");
   }
   for (let d of document.getElementsByTagName("button"))
      d.onclick = this.onPressed.bind(this);
}

new ButtonPressedLogger();      
<button>press me</button>
<button>no press me</button>


6

前述のように、Function.bind()関数が実行されるコンテキストを指定できます(つまりthis、関数の本体でキーワードが解決するオブジェクトを渡すことができます。

同様のサービスを実行するいくつかの類似したツールキットAPIメソッド:

jQuery.proxy()

Dojo.hitch()


3
/**
 * Bind is a method inherited from Function.prototype same like call and apply
 * It basically helps to bind a function to an object's context during initialisation 
 * 
 * */

window.myname = "Jineesh";  
var foo = function(){ 
  return this.myname;
};

//IE < 8 has issues with this, supported in ecmascript 5
var obj = { 
    myname : "John", 
    fn:foo.bind(window)// binds to window object
}; 
console.log( obj.fn() ); // Returns Jineesh

3

下記の簡単なプログラムを考えてみましょう。

//we create object user
let User = { name: 'Justin' };

//a Hello Function is created to Alert the object User 
function Hello() {
  alert(this.name);
}

//since there the value of this is lost we need to bind user to use this keyword
let user = Hello.bind(User);
user();

//we create an instance to refer the this keyword (this.name);

2

bind関数は、それが呼び出している関数と同じ関数本体を持つ新しい関数を作成します。これはthis引数で呼び出されます。:新しいインスタンスが作成されるたびに、最初の初期インスタンスを使用する必要がある場合は、bind funを使用します。bindfun.simplyをオーバーライドすることはできません。クラスの初期オブジェクトが格納されています。

setInterval(this.animate_to.bind(this), 1000/this.difference);

0

別の使用法は、バインドされた関数を、別の実行コンテキストで動作している別の関数に引数として渡すことができることです。

var name = "sample";
function sample(){
  console.log(this.name);
}
var cb = sample.bind(this);

function somefunction(cb){
  //other code
  cb();
}
somefunction.call({}, cb);

0

簡単な例

function lol(text) {
    console.log(this.name, text);
}

lol(); // undefined undefined
lol('first'); // undefined first
lol.call({name: 'karl'}); // karl undefined
lol.call({name: 'karl'}, 'second'); // karl second
lol.apply({name: 'meg'}); // meg undefined
lol.apply({name: 'meg'}, ['third']); // meg third
const newLol = lol.bind({name: 'bob'});
newLol(); // bob undefined
newLol('fourth'); // bob fourth

0

バインド方法

バインドの実装は次のようになります。

Function.prototype.bind = function () {
  const self = this;
  const args = [...arguments];
  const context = args.shift();

  return function () {
    return self.apply(context, args.concat([...arguments]));
  };
};

bind関数は、任意の数の引数を取り、新しい関数返すことができます

新しい関数は、JS Function.prototype.applyメソッドを使用して元の関数を呼び出します。この方法は、(そのコンテキストとして目的関数に渡される最初の引数を使用する)、および二番目の配列引数方法は、目標関数から残りの引数の組み合わせとなり、リターンを呼び出すために使用される引数と連結関数(この順序で)。 例は次のようになります。
applythisapply

function Fruit(emoji) {
  this.emoji = emoji;
}

Fruit.prototype.show = function () {
  console.log(this.emoji);
};

const apple = new Fruit('🍎');
const orange = new Fruit('🍊');

apple.show();  // 🍎
orange.show(); // 🍊

const fruit1 = apple.show;
const fruit2 = apple.show.bind();
const fruit3 = apple.show.bind(apple);
const fruit4 = apple.show.bind(orange);

fruit1(); // undefined
fruit2(); // undefined
fruit3(); // 🍎
fruit4(); // 🍊


0

簡単な説明:

bind()は、新しい関数を作成し、それがユーザーに返す関数で新しい参照を作成します。

このキーワードの後のパラメーターでは、事前構成するパラメーターを渡します。実際にはすぐには実行されず、実行の準備をするだけです。

必要な数だけパラメータを事前設定できます。

バインドを理解するための簡単な例:

function calculate(operation) {
  if (operation === 'ADD') {
   alert('The Operation is Addition');
  } else if (operation === 'SUBTRACT') {
   alert('The Operation is Subtraction');
  }
}

addBtn.addEventListener('click', calculate.bind(this, 'ADD'));
subtractBtn.addEventListener('click', calculate.bind(this, 'SUBTRACT'));

-1

bindは、javaスクリプトのプロトタイプで使用できる関数です。名前bind bindは、関数呼び出しをコンテキストにバインドするために使用されます。たとえば、

    var rateOfInterest='4%';
    var axisBank=
    {
    rateOfInterest:'10%',
    getRateOfInterest:function()
    {
    return this.rateOfInterest;
    }
    }
    axisBank.getRateOfInterest() //'10%' 


    let knowAxisBankInterest=axisBank.getRateOfInterest // when you want to assign the function call to a varaible we use this syntax
    knowAxisBankInterest(); // you will get output as '4%' here by default the function is called wrt global context

let knowExactAxisBankInterest=knowAxisBankInterest.bind(axisBank);     //so here we need bind function call  to its local context


    knowExactAxisBankInterest() // '10%' 

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