MDN中bind是这样定义的:
bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。
由此我们可以看出bind 函数的两个特点:
1. 绑定this,返回一个新函数,便于稍后调用;
2. 可以传入参数 (可以预传参,只需要传入剩下的参数)
看个bind应用的例子:
var person = {
name: 'nuan'
}
function sayName(prefix, suffix){
console.log(prefix + this.name + suffix) // Hello, nuan???
}
var newSayName = sayName.bind(person,'Hello, ')
newSayName('???')
下面从bind函数的两个特点进行实现:
为了满足第一个返回一个新函数的特点,下面是个简化版的bind实现:
Function.prototype.bind = function(context){
var self = this; //保存原函数
return function(){ //返回一个新的函数
return self.apply(context, arguments); //执行新的函数的时候,会把之前传入的context当做新函数体内的this
}
}
var obj = {
name: 'sven'
}
var func = function(){
console.log(this.name); //sven
}.bind(obj);
func();
为了满足第二个bind函数可以预传参,只需要传入剩下的参数的特点,最终实现如下:
Function.prototype.bind = function () {
var self = this, //保存原函数
context = [].shift.call(arguments), //需要绑定的this上下文
args = [].slice.call(arguments); //剩余的参数转为数组
return function(){ //返回一个新的函数
return self.apply(context, [].concat.call(args, [].slice.call(arguments)));
//执行新的函数的时候,会把之前传入的context当做新函数体内的this
//并且组合两次分别传入的参数,作为新函数的参数
}
}
var obj = {
name: 'sven'
}
var func = function(a, b, c, d) {
console.log(this.name); //sven
console.log([a, b, c, d]); //[1, 2, 3, 4]
}.bind(obj, 1, 2);
func(3, 4);
参考阅读