使用JavaScript'bind'方法

San*_*mar 580 javascript bind function

bind()在JavaScript中有什么用?

nkr*_*ron 553

Bind创建一个新函数,该函数将this设置为传递给的第一个参数bind().

这是一个示例,显示如何使用bind传递成员方法具有正确的成员方法this:

var Button = function(content) { 
  this.content = content;
};
Button.prototype.click = function() {
  console.log(this.content + ' clicked');
};

var myButton = new Button('OK');
myButton.click();

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

var boundClick = myButton.click.bind(myButton);
boundClick(); // bound, 'this' is myButton
Run Code Online (Sandbox Code Playgroud)

打印出来:

OK clicked
undefined clicked
OK clicked
Run Code Online (Sandbox Code Playgroud)

您还可以在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));
Run Code Online (Sandbox Code Playgroud)

打印出来:

15
Run Code Online (Sandbox Code Playgroud)

查看JavaScript函数绑定以获取更多信息和交互式示例.

更新:ECMAScript 2015增加了对=>功能的支持. =>函数更紧凑,不会将this指针从其定义范围更改,因此您可能不需要bind()经常使用.例如,如果您希望Button第一个示例中的函数将click回调挂钩到DOM事件,则以下是执行此操作的所有有效方法:

Button.prototype.hookEvent(element) {
  // Use bind() to ensure 'this' is the 'this' inside click()
  element.addEventListener('click', this.click.bind(this));
};
Run Code Online (Sandbox Code Playgroud)

要么:

Button.prototype.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() });
}
Run Code Online (Sandbox Code Playgroud)

要么:

Button.prototype.hookEvent(element) {
  // => functions do not change 'this', so you can use it directly
  element.addEventListener('click', () => this.click());
}
Run Code Online (Sandbox Code Playgroud)

  • 如果有人想知道为什么looseClick()没有绑定到myButton,那是因为"this"指的是调用该函数的对象(looseClick()).调用looseClick()的对象是全局对象. (35认同)
  • 很好的解释,但我很难找到我想要使用你描述的第三个选项而不是第一个选项的例子.你能描述一下你觉得需要使用第三种选择的情况吗? (5认同)
  • 我不认为我曾经使用过绑定而非绑定'this'.另一种形式称为[部分应用](http://en.wikipedia.org/wiki/Partial_application),在功能语言中很常见.我认为它包含在内以保证完整性. (4认同)
  • @Darryl - 从事件处理程序传递参数的一个原因.如果你有这个反应代码:`var Note = React.createClass({add:function(text){...},render:function(){return <button onClick = {this.add.bind(null,"New注意")} />}}`,然后当单击按钮时,它会将参数文本"New Note"传递给`add`方法. (3认同)

Ren*_*M G 214

最简单的用法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
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此链接

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

  • 我见过的最好的bind()介绍. (24认同)
  • 很好的答案,因为您的示例不需要有关初学者可能不熟悉的语言功能(例如“原型”)的知识。 (2认同)
  • 这是迄今为止理解`bind`的最简单方法.奖励! (2认同)

Jha*_*bub 166

绑定允许 -

  • 将"this"的值设置为特定对象.这变得非常有用,因为有时不是预期的.
  • 重用方法
  • 咖喱功能

例如,您可以扣除每月的俱乐部费用

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

现在,您希望将此功能重新用于其他俱乐部会员.请注意,每月费用因会员而异.

让我们假设雷切尔的余额为500,每月会员费为90.

var rachel = {name:'Rachel Green', total:500};
Run Code Online (Sandbox Code Playgroud)

现在,创建一个可以反复使用的功能,每月从她的帐户中扣除费用

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

现在,相同的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
Run Code Online (Sandbox Code Playgroud)

  • 在您的示例中,我认为我倾向于设置使用new关键字实例化的成员对象,其中每个成员都有自己的属性/方法.然后它只是ross.getMonthlyFee(25)的问题.这个例子只是为了演示bind()的使用,还是你的方法有一些优势? (9认同)
  • @KhanSharp你的答案是正确的,但正是你对电视剧《老友记》的引用让我发表了评论和点赞。谢谢你的回答。 (2认同)

Joh*_*ers 72

该MDN文档Function.prototype.bind():

绑定()方法创建一个新的功能,调用它时,具有其将此关键字设置为所提供的值,与前述的当新功能被调用任何设置参数给定的序列.

那是什么意思?!

好吧,让我们看一个如下所示的函数:

var logProp = function(prop) {
    console.log(this[prop]);
};
Run Code Online (Sandbox Code Playgroud)

现在,让我们看一个看起来像这样的对象:

var Obj = {
    x : 5,
    y : 10
};
Run Code Online (Sandbox Code Playgroud)

我们可以将函数绑定到我们的对象,如下所示:

Obj.log = logProp.bind(Obj);
Run Code Online (Sandbox Code Playgroud)

现在,我们可以Obj.log在代码中的任何位置运行:

Obj.log('x'); // Output : 5
Obj.log('y'); // Output : 10
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为我们绑定this了对象的值Obj.


真正有趣的地方是,当你不仅绑定一个值this,而且还为它的参数绑定prop:

Obj.logX = logProp.bind(Obj, 'x');
Obj.logY = logProp.bind(Obj, 'y');
Run Code Online (Sandbox Code Playgroud)

我们现在可以这样做:

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
Run Code Online (Sandbox Code Playgroud)

与之不同Obj.log,我们不必传递x或者y,因为我们在进行绑定时传递了这些值.

  • 这个答案应该得到更多的爱.好解释. (7认同)

小智 19

变量具有本地和全球范围.假设我们有两个具有相同名称的变量.一个是全局定义的,另一个是在函数闭包内定义的,我们想要得到函数闭包内的变量值.在这种情况下,我们使用这个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();
Run Code Online (Sandbox Code Playgroud)
<p id="demo1">0</p>
<p id="demo2">0</p>
Run Code Online (Sandbox Code Playgroud)


Wil*_*een 15

摘要:

bind()方法将对象作为第一个参数并创建一个新函数.调用函数this时,函数体中的值将是作为函数中的参数传入的对象bind().

this无论如何,在JS中如何工作

thisjavascript中的值依赖于取决于调用函数的Object.它的值总是指点的左边的对象,调用函数的位置.在全球范围内的情况下,这是window(或globalnodeJS).只有call,apply并且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
Run Code Online (Sandbox Code Playgroud)

如何使用绑定?

绑定可以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'
Run Code Online (Sandbox Code Playgroud)

一旦函数绑定到特定this值,我们就可以传递它,甚至将它放在其他对象的属性上.价值this将保持不变.

  • 您在代码中对obj的注释是对象,因为它在点的左边,而window是对象,因为它是window.custFunc()的简写,而window在点的左边是对我很有见识。 (3认同)

小智 12

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

在javascript中绑定是一个方法 - Function.prototype.bind.bind是一种方法.它被称为函数原型.此方法创建一个函数,其主体类似于调用它的函数,但'this'指的是传递给bind方法的第一个参数.它的语法是

     var bindedFunc = Func.bind(thisObj,optionsArg1,optionalArg2,optionalArg3,...);
Run Code Online (Sandbox Code Playgroud)

例: -

  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;
Run Code Online (Sandbox Code Playgroud)


Ott*_*tti 10

bind()方法创建一个新的函数实例,该值绑定到传递给bind()的值.例如:

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

这里,通过调用bind()并传入对象o,从sayColor()创建一个名为objectSayColor()的新函数.objectSayColor()函数具有等于o的this值,因此即使作为全局调用,调用该函数也会导致显示字符串"blue".

参考:Nicholas C. Zakas - 面向WEB开发人员的专业JAVASCRIPT®


cdi*_*ins 9

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

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

部分申请

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

高阶函数(HOF)

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

绑定多个参数

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

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

let multiplyBy10 = multiply.bind(null, 10);
console.log(multiplyBy10(5));
Run Code Online (Sandbox Code Playgroud)

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

在最常见的用例中,当使用一个参数调用时,该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));
Run Code Online (Sandbox Code Playgroud)

实现有状态回调

以下示例显示了如何使用绑定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();      
Run Code Online (Sandbox Code Playgroud)
<button>press me</button>
<button>no press me</button>
Run Code Online (Sandbox Code Playgroud)


mty*_*son 5

如上所述,Function.bind()允许您指定函数将在其中执行的上下文(也就是说,它允许您传递this关键字将在函数体中解析的对象.

一些执行类似服务的类似工具包API方法:

jQuery.proxy()

Dojo.hitch()