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

JavaScript中的bind()有什么用?

539826 次浏览

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 clickedundefined clickedOK clicked

您还可以在第一个(this)参数之后添加额外的参数,bind将这些值传递给原始函数。您稍后传递给绑定函数的任何其他参数都将在绑定参数之后传递:

// Example showing binding some parametersvar 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 abovehookEvent(element) {// Use bind() to ensure 'this' is the 'this' inside click()element.addEventListener('click', this.click.bind(this));}};

或:

var myButton = {... // As abovehookEvent(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 abovehookEvent(element) {// => functions do not change 'this', so you can use it directlyelement.addEventListener('click', () => this.click());}};

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

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

绑定允许

  • 将“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};

现在,创建一个函数,可以一次又一次地使用,每个月从她的账户中扣除费用

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

现在,相同的getMonthlyFee函数可用于另一个会员的不同会员费。例如,Ross Geller有250的余额和25的月费

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

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 modulevar boundGetX = getX.bind(module);boundGetX(); // 81

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

Function.prototype.bind()

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

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

jQuery.proxy()

Dojo.hitch()

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

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 rangevar result = boundedFunc(15); //passing valueconsole.log(result) // will give true;
/*** 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 5var obj = {myname : "John",fn:foo.bind(window)// binds to window object};console.log( obj.fn() ); // Returns Jineesh

MDN文档Function.prototype.bind()

绑定方法创建一个新函数,当调用该函数时,它具有其this关键字设置为提供的值,具有给定的序列调用新函数时提供的任何前面的参数。

那是什么意思?!

让我们看一个看起来像这样的函数:

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 : 5Obj.log('y'); // Output : 10

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


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

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

我们现在可以这样做:

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

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

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

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 10console.log(ApplyFunction(mul.multiply, 10));
// Produces expected result: 50console.log(ApplyFunction(mul.multiply.bind(mul), 10));

实现有状态的CallBack

下面的示例显示了使用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>

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值,因此调用该函数,即使作为全局调用,也会导致显示字符串“蓝色”。

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

变量有局部和全局作用域。假设我们有两个同名的变量。一个是全局定义的,另一个是在函数闭包中定义的,我们想获取函数闭包中的变量值。在这种情况下,我们使用这个bind()方法。请参阅下面的简单示例:

var x = 9; // this refers to global "window" object here in the browservar 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>

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 syntaxknowAxisBankInterest(); // 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%' 

总结:

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是如何使用的?

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

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

var name = "sample";function sample(){console.log(this.name);}var cb = sample.bind(this);
function somefunction(cb){//other codecb();}somefunction.call({}, cb);

简单的例子

function lol(second, third) {console.log(this.first, second, third);}
lol(); // undefined, undefined, undefinedlol('1'); // undefined, "1", undefinedlol('1', '2'); // undefined, "1", "2"
lol.call({first: '1'}); // "1", undefined, undefinedlol.call({first: '1'}, '2'); // "1", "2", undefinedlol.call({first: '1'}, '2', '3'); // "1", "2", "3"
lol.apply({first: '1'}); // "1", undefined, undefinedlol.apply({first: '1'}, ['2', '3']); // "1", "2", "3"
const newLol = lol.bind({first: '1'});newLol(); // "1", undefined, undefinednewLol('2'); // "1", "2", undefinednewLol('2', '3'); // "1", "2", "3"
const newOmg = lol.bind({first: '1'}, '2');newOmg(); // "1", "2", undefinednewOmg('3'); // "1", "2", "3"
const newWtf = lol.bind({first: '1'}, '2', '3');newWtf(); // "1", "2", "3"

绑定方法绑定方法

绑定实现可能看起来像这样:

Function.prototype.bind = function () {const self = this;const args = [...arguments];const context = args.shift();
return function () {return self.apply(context, args.concat([...arguments]));};};

bind函数可以接受任意数量的参数和返回一个新函数

新功能将使用JSFunction.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(); // undefinedfruit2(); // undefinedfruit3(); // 🍎fruit4(); // 🍊

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

//we create object userlet User = { name: 'Justin' };
//a Hello Function is created to Alert the object Userfunction Hello() {alert(this.name);}
//since there the value of this is lost we need to bind user to use this keywordlet user = Hello.bind(User);user();
//we create an instance to refer the this keyword (this.name);

简单解释:

绑定创建一个新函数,一个新的引用在它返回给你的函数。

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

您可以根据需要预先配置尽可能多的参数。

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

除了上面所说的,bind()方法允许一个对象从另一个对象借用一个方法而不复制该方法。这在JavaScript中被称为函数借用

我没有阅读上面的代码,但我学到了一些简单的东西,所以想在这里分享绑定方法后绑定方法,我们可以将其用作任何正常方法。

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

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

  • 它将调用函数绑定到传递的Object并返回一样的

  • 当一个对象绑定到一个函数时,这意味着你将能够使用从函数中访问该对象的值'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;}

因此,Power OfTwo会找到第二种力量。

请随意检查这个。

JavaScript中的bind()函数

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))}
// usagefunction 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 someThisadd5 = 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

这是最简单的解释:

假设你有一个功能

function _loop(n) { console.log("so: " + n) }

显然,你可以像往常一样称之为_loop(69)

像这样重写:

var _loop = function() { console.log("so: " + this.n) }

注意现在有

  • 没有这样的论点
  • 您可以使用“this”来获取命名参数

你现在可以像这样调用函数:

 _loop.bind( {"n": 420} )

就这样了。

最典型的用例:

一个真正典型的用法是当你需要将参数添加到回调时。

回调不能有参数。

所以只要像上面那样“重写”回调。