JavaScript的“绑定”方法有什么用?


650

bind()在JavaScript中有什么用?


8
我的标准用例:select = document.querySelector.bind(document)
将于

1
^对于任何想知道的人,需要这样做的原因是因为this否则会引用window全局对象。使用document.querySelector.bind(document),我们确保“是select”是thisdocument,而不是window。但是,如果我误解了,有人可以纠正我。
AleksandrH

Answers:


612

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

您还可以在1st(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 Function绑定以获取更多信息和交互式示例。

更新: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
极好的外植体,但我正在努力寻找一些示例,在这些示例中,我想使用您描述的第三个选项而不是第一个选项。您能描述一下您需要使用第三个选项的情况吗?
达里尔

5
我认为除了绑定“ this”之外,我从未使用过绑定。另一种形式称为部分应用程序,在功能语言中非常常见。我想它是出于完整性考虑。
nkron 2015年

42
如果有人想知道为什么不将松散点击()绑定到myButton,那是因为“ this”是指调用函数(looseClick())的对象。调用PineClick()的对象是全局对象。
pokero,2015年

4
@Darryl-原因之一就是要从事件处理程序传递参数。如果您有此反应代码:var Note = React.createClass({ add: function(text){ ... }, render: function () { return <button onClick={this.add.bind(null, "New Note")}/> } },则单击按钮时,它将参数文本“ New Note”传递给该add方法。
P. Myer Nore

2
“您还可以在第一个参数之后添加额外的参数,并且bind会将这些值传递给原始函数,然后再传递给绑定函数传递额外的参数:”这种说法令人困惑。
肯·英格拉姆

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/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind


38
我见过的关于bind()的最佳介绍。
thomasfl

3
很好的答案,因为您的示例不需要prototype新手入门的语言功能知识(例如)。
爱德华

1
简洁明了!
6

172

绑定允许-

  • 将“ this”的值设置为特定对象。这有时很有用,因为不是预期的。
  • 重用方法
  • 咖喱功能

例如,您有一个扣除每月俱乐部费用的功能

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

现在,您想对其他俱乐部会员重用此功能。请注意,会员的月费会有所不同。

假设Rachel的余额为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
在您的示例中,我认为我倾向于设置一个用new关键字实例化的成员对象,其中每个成员都有自己的属性/方法。然后,这仅仅是ross.getMonthlyFee(25)的问题。这个示例仅仅是为了演示bind()的用法,还是您的方法有一些优势?
Darryl 2015年

爱咖喱一个功能!
杰瑞·刘

我不知道,但是我会做var getRachelFee = getMonthlyFee(rachel,90); 函数通常是函数getMonthlyFee(member,fee){}。
米格尔(Miguel)

1
@KhanSharp您的回答是正确的,但这是您对电视连续剧《朋友》的引用使我发表评论和赞扬。谢谢您的回答🤗。
萨拉·伦德

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

之所以可行,是因为我们将value绑定this到了object Obj


真正有趣的地方是,您不仅要绑定的值this,而且还要绑定其参数prop

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

我们现在可以这样做:

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

与with不同Obj.log,我们不必传递xy,因为在进行绑定时我们传递了这些值。


9
这个答案应该得到更多的爱。好解释。
Chax

一般概述和特定示例的很好结合。
肯·英格拉姆

直线上升100升的按钮在哪里?
kushalvm

与此相关,我还建议您阅读部分应用的函数的 MDN文档部分,以了解绑定“ null”的用法。对于大多数绑定使用,它应该关闭门。 developer.mozilla.org/en/docs/Web/JavaScript/Reference/…–
kushalvm

23

变量具有局部和全局范围。假设我们有两个具有相同名称的变量。一个是全局定义的,另一个是在函数闭包内部定义的,我们想要获取函数闭包内部的变量值。在这种情况下,我们使用此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可以不同地更改此绑定。这是显示此关键字如何工作的示例:

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,

12

我将在理论上和实践上解释绑定

javascript中的bind是一种方法-Function.prototype.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”转换为您传入的任何对象,对吗?
哈维·林

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-适用于Web开发人员的专业JAVASCRIPT®


简洁明了的示例
艾哈迈德·谢里夫

9

通过将参数绑定到值来创建新函数

bind方法从另一个函数创建一个新函数,其中一个或多个参数绑定到特定值,包括隐式this参数。

部分申请

这是部分应用的示例。通常我们提供一个带有所有参数的函数,该函数产生一个值。这称为功能应用程序。我们正在将该函数应用于其参数。

高阶函数(HOF)

部分应用是高阶函数(HOF)的一个示例,因为它产生的新函数具有较少的参数。

绑定多个参数

您可以bind用来将具有多个参数的函数转换为新函数。

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

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

从实例方法转换为静态函数

在最常见的用例中,当使用一个参数调用该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。:每次创建一个新实例时,我们必须使用第一个初始实例,然后使用bind fun。我们无法覆盖bind fun。它只是存储了该类的初始对象。

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方法调用原始函数。
apply方法将使用传递给目标函数的第一个参数作为其上下文(this),该apply方法的第二个数组参数将是目标函数中其余参数的组合,concat与用于调用return的参数功能(按此顺序)。

一个例子可能看起来像这样:

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用于将函数调用绑定到上下文,无论您处理的是哪个,例如:

    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%' 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.