bind()方法创建一个新的函数,在调用时设置this关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。
原文地址
语法: function .bind(thisArg[, arg1[, arg2[, ...]]])
thisArg: 调用绑定函数时作为this参数传递给目标函数的值。 如果使用new 运算符构造绑定函数,则忽略该值。当使用bind在setTimeout中创建一个函数(作为回调提供)时,作为thisArg传递的任何原始值都将转换为object。如果bind函数的参数列表为空,执行作用域的this将被视为新函数的thisArg。
arg1, arg2, … 当目标函数被调用时,预先添加到绑定函数的参数列表中的参数。
### 返回值:
返回一个原函数的拷贝,并拥有指定的this值和初始参数。
示例: 创建绑定函数
bind() 最简单的用法是创建一个函数,不论怎么调用,这个函数都有同样的 this 值。JavaScript新手经常犯的一个错误是将一个方法从对象中拿出来,然后再调用,期望方法中的 this 是原来的对象(比如在回调中传入这个方法)。如果不做特殊处理的话,一般会丢失原来的对象。基于这个函数,用原始的对象创建一个绑定函数,巧妙地解决了这个问题:
this .x = 9 ; var module = { x: 81 , getX: function ( ) { return this .x; } }; module .getX(); var retrieveX = module .getX;retrieveX(); var boundGetX = retrieveX.bind(module );boundGetX();
偏函数 bind()的另一个最简单的用法是使一个函数拥有预设的初始参数。只要将这些参数(如果有的话)作为bind()的参数写在this后面。当绑定函数被调用时,这些参数会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们后面。
function list ( ) { return Array .prototype.slice.call(arguments ); } function addArguments (arg1, arg2 ) { return arg1 + arg2 } var list1 = list(1 , 2 , 3 ); var result1 = addArguments(1 , 2 ); var leadingThirtysevenList = list.bind(null , 37 );var addThirtySeven = addArguments.bind(null , 37 ); var list2 = leadingThirtysevenList(); var list3 = leadingThirtysevenList(1 , 2 , 3 ); var result2 = addThirtySeven(5 ); var result3 = addThirtySeven(5 , 10 );
在默认情况下,使用 window.setTimeout() 时,this 关键字会指向 window (或global)对象。当类的方法中需要 this 指向类的实例时,你可能需要显式地把 this 绑定到回调函数,就不会丢失该实例的引用。
function LateBloomer ( ) { this .petalCount = Math .ceil(Math .random() * 12 ) + 1 ; } LateBloomer.prototype.bloom = function ( ) { window .setTimeout(this .declare.bind(this ), 1000 ); }; LateBloomer.prototype.declare = function ( ) { console .log('I am a beautiful flower with ' + this .petalCount + ' petals!' ); }; var flower = new LateBloomer();flower.bloom();
快捷调用 在你想要为一个需要特定的 this 值的函数创建一个捷径(shortcut)的时候,bind() 也很好用。 你可以用 Array.prototype.slice 来将一个类似于数组的对象(array-like object)转换成一个真正的数组,就拿它来举例子吧。你可以简单地这样写:
var slice = Array .prototype.slice;slice.apply(arguments );
用 bind()可以使这个过程变得简单。在下面这段代码里面,slice 是 Function.prototype 的 apply() 方法的绑定函数,并且将 Array.prototype 的 slice() 方法作为 this 的值。这意味着我们压根儿用不着上面那个 apply()调用了。
var unboundSlice = Array .prototype.slice;var slice = Function .prototype.apply.bind(unboundSlice);slice(arguments );
Polyfill if (!Function .prototype.bind) { Function .prototype.bind = function (oThis ) { if (typeof this !== 'function' ) { throw new TypeError ('Function.prototype.bind - what is trying to be bound is not callable' ); } var aArgs = Array .prototype.slice.call(arguments , 1 ), fToBind = this , fNOP = function ( ) {}, fBound = function ( ) { return fToBind.apply(this instanceof fBound ? this : oThis, aArgs.concat(Array .prototype.slice.call(arguments ))); }; if (this .prototype) { fNOP.prototype = this .prototype; } fBound.prototype = new fNOP(); return fBound; }; }