JavaScript“绑定”方法有啥用?

Posted

技术标签:

【中文标题】JavaScript“绑定”方法有啥用?【英文标题】:What is the use of the JavaScript 'bind' method?JavaScript“绑定”方法有什么用? 【发布时间】:2011-01-15 06:10:18 【问题描述】:

bind()javascript 中有什么用?

【问题讨论】:

调用函数可以看成ptr.func(),提供上下文的是ptr 【参考方案1】:

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 Function bind 了解更多信息和互动示例。

更新: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());
  
;

【讨论】:

很好的解释,但我很难找到我想使用你描述的第三个选项而不是第一个选项的例子。您能否描述您认为需要使用第三个选项的情况? @Darryl - 从事件处理程序传递参数的原因之一。如果你有这个反应代码:var Note = React.createClass( add: function(text) ... , render: function () return <button onClick=this.add.bind(null, "New Note")/> ,那么当点击按钮时,它会传递一个参数文本“New Note”给add方法。【参考方案2】:

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

有关更多信息,请参阅 MDN Web Docs 上的此链接:

Function.prototype.bind()

【讨论】:

我见过的最好的bind()介绍。 很好的答案,因为您的示例不需要了解初学者可能不熟悉的语言特性(例如 prototype)。【参考方案3】:

bind 允许-

将“this”的值设置为特定对象。这变得非常有帮助,因为有时 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

【讨论】:

在您的示例中,我想我倾向于设置一个使用 new 关键字实例化的成员对象,其中每个成员都有自己的属性/方法。那么这只是 ross.getMonthlyFee(25) 的问题。这个例子只是为了演示 bind() 的使用,还是你的方法有一些优势? 爱咖喱一个功能! 我不知道,但我会做 var getRachelFee = getMonthlyFee(rachel, 90);函数将是 function getMonthlyFee(member,fee) 类似的东西。 @KhanSharp 您的回答是正确的,但正是您对电视剧《老友记》的提及让我发表了评论和投票。谢谢你的回答?。【参考方案4】:

来自the MDN docsFunction.prototype.bind()

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 不同,我们不必传递xy,因为我们在绑定时传递了这些值。

【讨论】:

这个答案应该得到更多的爱。解释得很好。 一般概述和具体示例很好的结合。 直升100次的按钮在哪里? 有了这个,我还建议阅读部分应用函数的 MDN 文档部分,以了解绑定“null”的使用。对于大多数绑定使用,它应该关闭门。 developer.mozilla.org/en/docs/Web/JavaScript/Reference/… 谢谢!很多人只是链接文档(或刻薄地留下 LMGTFY 链接),但对于初学者来说,即使是文档也很难理解。【参考方案5】:

变量具有本地和全局范围。假设我们有两个同名的变量。一个是全局定义的,另一个是在函数闭包内定义的,我们想要获取函数闭包内的变量值。在这种情况下,我们使用这个 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>

【讨论】:

【参考方案6】:

总结:

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

this 在 JS 中是如何工作的

javascript 中this 的值始终取决于调用函数的对象。 this 的值始终是指点左侧的对象,从那里调用函数。在全局范围的情况下,这是window(或nodeJS 中的global)。只有 callapplybind 可以不同地更改 this 绑定。下面是一个展示 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

绑定是如何使用的?

Bind 可以帮助克服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 的值将保持不变。

【讨论】:

您的代码中关于 obj 的 cmets 是对象,因为它位于点的左侧,window 是对象,因为它是 window.custFunc() 的简写,而 window 是左侧点对我来说非常有见地。 很好的答案,这个答案让一切都清楚了。【参考方案7】:

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

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”变成了你传入的任何对象,对吗?【参考方案8】:

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

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

部分申请

这是partial application 的示例。通常我们提供一个函数,它的所有参数都会产生一个值。这被称为函数应用程序。我们将函数应用于它的参数。

高阶函数 (HOF)

部分应用程序是higher order function (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>

【讨论】:

【参考方案9】:

bind() 方法创建一个新函数实例,其 this 值绑定到传递给 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®

【讨论】:

简洁明了的例子【参考方案10】:

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

几个执行类似服务的类似工具包 API 方法:

jQuery.proxy()

Dojo.hitch()

【讨论】:

【参考方案11】:
/**
 * 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

【讨论】:

【参考方案12】:

Bind Method

绑定实现可能如下所示:

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

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

绑定函数可以接受任意数量的参数并返回一个新函数新函数将使用 JS 的 Function.prototype.apply 方法调用原始函数。apply 方法将使用传递给目标函数的第一个参数作为其上下文(this),apply 方法的第二个数组参数将是来自目标函数的其余参数的组合,与用于调用返回函数的参数相连接(按此顺序)。 示例可能如下所示:

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(); // ?

【讨论】:

【参考方案13】:

考虑下面列出的简单程序,

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

【讨论】:

【参考方案14】:

简单说明:

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

【讨论】:

【参考方案15】:

bind 函数创建一个新函数,其函数体与它正在调用的函数相同。它使用 this 参数调用。为什么我们使用 bind fun。 : 当每次创建一个新实例并且我们必须使用第一个初始实例时,我们使用绑定乐趣。我们不能覆盖绑定乐趣。只是它存储了类的初始对象。

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

【讨论】:

【参考方案16】:

简单示例

function lol(second, third) 
    console.log(this.first, second, third);


lol(); // undefined, undefined, undefined
lol('1'); // undefined, "1", undefined
lol('1', '2'); // undefined, "1", "2"

lol.call(first: '1'); // "1", undefined, undefined
lol.call(first: '1', '2'); // "1", "2", undefined
lol.call(first: '1', '2', '3'); // "1", "2", "3"

lol.apply(first: '1'); // "1", undefined, undefined
lol.apply(first: '1', ['2', '3']); // "1", "2", "3"

const newLol = lol.bind(first: '1'); 
newLol(); // "1", undefined, undefined
newLol('2'); // "1", "2", undefined
newLol('2', '3'); // "1", "2", "3"

const newOmg = lol.bind(first: '1', '2');
newOmg(); // "1", "2", undefined
newOmg('3'); // "1", "2", "3"

const newWtf = lol.bind(first: '1', '2', '3');
newWtf(); // "1", "2", "3"

【讨论】:

【参考方案17】:

function.prototype.bind() 接受一个对象。

它将调用函数绑定到传递的对象和返回 一样的。

当一个对象绑定到一个函数时,这意味着你将能够 使用从函数内部访问该对象的值 'this' 关键字。

也可以这样说,

function.prototype.bind() 用于提供/更改一个上下文 功能。

let powerOfNumber = function(number) 
  let product = 1;
    for(let i=1; i<= this.power; i++) 
      product*=number;
  
  return product;



let powerOfTwo = powerOfNumber.bind(power:2);
alert(powerOfTwo(2));

let powerOfThree = powerOfNumber.bind(power:3);
alert(powerOfThree(2));

let powerOfFour = powerOfNumber.bind(power:4);
alert(powerOfFour(2));

让我们试着理解这一点。

    let powerOfNumber = function(number) 
      let product = 1;
      for (let i = 1; i <= this.power; i++) 
        product *= number;
      
      return product;
    

这里,在这个函数中,this对应绑定到函数powerOfNumber的对象。目前我们没有任何绑定到这个函数的函数。

让我们创建一个函数 powerOfTwo,它会使用上面的函数找到数字的二次方。

  let powerOfTwo = powerOfNumber.bind(power:2);
  alert(powerOfTwo(2));

这里对象 power : 2 使用绑定传递给 powerOfNumber 函数。

绑定函数将此对象绑定到 powerOfNumber() 并将以下函数返回给 powerOfTwo。现在,powerOfTwo 看起来像,

    let powerOfNumber = function(number) 
      let product = 1;
        for(let i=1; i<=2; i++) 
          product*=number;
      
      return product;
    

因此,powerOfTwo 将找到第二个幂。

请随意查看。

bind() function in Javascript

【讨论】:

【参考方案18】:

bind() 方法创建一个新函数,在调用该函数时,其 this 关键字设置为提供的值,并且在调用新函数时在任何提供的参数之前具有给定的参数序列。

第一部分的示例

从反应包useSt8中获取

import  useState  from "react"

function st8() 
    switch(arguments.length) 
        case 0: return this[0]
        case 1: return void this[1](arguments[0])
        default: throw new Error("Expected 0 or 1 arguments")
    



function useSt8(initial) 
    // this in st8 will be something like [state, setSatate]
    return st8.bind(useState(initial))


// usage
function Counter() 
  const count = useSt8(0);
  return (
    <>
      Count: count()
      <button onClick=() => count(0)>Reset</button>
      <button onClick=() => count(prevCount => prevCount + 1)>inc</button>
    </>
  );

第二部分的例子

const add = (a, b) => a+b

someThis = this
// new function with this value equal to someThis
add5 = add.bind(someThis, 5) 
add5(10) // 15

// we don't use this in add decelartion so this will work too.
add10 = add.bind(null, 10) 
add10(5) // 15

【讨论】:

【参考方案19】:

另一种用法是您可以将绑定函数作为参数传递给在另一个执行上下文下运行的另一个函数。

var name = "sample";
function sample()
  console.log(this.name);

var cb = sample.bind(this);

function somefunction(cb)
  //other code
  cb();

somefunction.call(, cb);

【讨论】:

【参考方案20】:

除了已经说过的,bind() 方法允许一个对象从另一个对象借用一个方法,而无需复制该方法。这在 JavaScript 中称为 函数借用

【讨论】:

“不复制”是什么意思? 这意味着您不需要复制功能代码并将其粘贴到任何其他需要此功能的对象中;这是扩展功能的好方法。 @Bergi 您永远不需要复制源代码。您可以将现有功能分配给您的其他对象,您不需要为此使用bind【参考方案21】:

我没有读过上面的代码,但是我学到了一些简单的东西,所以想在这里分享一下绑定方法之后的绑定方法,我们可以像任何普通方法一样使用它。

<pre> note: do not use arrow function it will show error undefined  </pre>

let solarSystem = 
    sun: 'red',
    moon : 'white',
    sunmoon : function()
       let dayNight = this.sun + ' is the sun color and present in day and '+this.moon + ' is the moon color and prenet in night';
        return dayNight;
    


let work = function(work,sleep)
    console.log(this.sunmoon()); // accessing the solatSystem it show error undefine sunmmon untill now because we can't access directly for that we use .bind()
    console.log('i work in '+ work +' and sleep in '+sleep);


let outPut = work.bind(solarSystem);
outPut('day','night')

【讨论】:

【参考方案22】:

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

【讨论】:

以上是关于JavaScript“绑定”方法有啥用?的主要内容,如果未能解决你的问题,请参考以下文章

javaScript中的setTimeout返回值有啥用?

javascript中的.then函数有啥用? [复制]

面试题 java啥叫事务,事务有啥用

JavaScript continue语句有啥用?

jquery 与 javascript 有啥关系?jquery 干啥用的?

表单中<label>标签有啥用?