使用JavaScript'bind'方法

时间:2010-02-10 12:33:48

标签: javascript function bind

JavaScript中bind()的用途是什么?

22 个答案:

答案 0 :(得分:512)

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

打印出来:

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事件,则以下是执行此操作的所有有效方法:

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

或者:

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

或者:

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

答案 1 :(得分:165)

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

答案 2 :(得分:152)

bind允许 -

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

答案 3 :(得分:66)

来自Function.prototype.bind()上的the MDN docs

  

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

答案 4 :(得分:13)

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

答案 5 :(得分:12)

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

在javascript中绑定是一个方法 - 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;

答案 6 :(得分:9)

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()函数具有等于o的this值,因此即使作为全局调用,调用该函数也会导致显示字符串“blue”。

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

答案 7 :(得分:9)

摘要:

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

this在JS中如何工作

javascript中this的值始终取决于所调用的对象。 此值始终是指点在函数被调用处的左侧对象。如果是全局范围,则为window(或global中的nodeJS)。仅callapplybind可以不同地更改此绑定。这是显示此关键字如何工作的示例:

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的值将保持不变。

答案 8 :(得分: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 :(得分:5)

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

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

jQuery.proxy()

Dojo.hitch()

答案 10 :(得分:3)

简单说明:

bind()创建一个新函数,该函数将返回给您一个新引用。

在此关键字之后的参数中,传递您要预配置的参数。实际上,它不会立即执行,只是为执行做准备。

您可以根据需要预先配置许多参数。

了解绑定的简单示例:

using (var context = new GlassesMVDataContext())
{
}

答案 11 :(得分: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

答案 12 :(得分: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);

答案 13 :(得分:1)

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

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

答案 14 :(得分:1)

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

bind函数可以接受任意数量的参数,并返回新函数

新函数将使用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(); // ?

答案 15 :(得分:1)

简单示例

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"

答案 16 :(得分:0)

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

这里使用 bind 将对象 {power : 2} 传递给 powerOfNumber 函数。

bind 函数将此对象绑定到 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

答案 17 :(得分:0)

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

第一部分示例

<块引用>

从 react 包 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

答案 18 :(得分:0)

我没有阅读上面的代码,但我学到了一些简单的知识,因此想在这里分享关于bind方法的知识,我们可以将bind方法用作任何普通方法。

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

答案 19 :(得分:0)

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

答案 20 :(得分:0)

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

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

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

答案 21 :(得分:-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%'