bind 的功能介绍
bind() 方法会创建一个新函数,当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的的参数。
注意点:
- 跟 call、apply 一样都是会绑定 this,但 bind 不会立即执行,而是返回一个函数等待用户的执行。
- bind 可以预存参数。
- bind 返回的新函数作为 new 构造函数调用时会忽略默认提供的 this,但预存参数不会。
// 用法
var foo = {
value: 1
};
function bar() {
console.log(this.value);
}
// 返回了一个函数
var bindFoo = bar.bind(foo);
bindFoo() // 1
// new 构造函数调用
function bar(name, age) {
this.habit = 'exercise';
console.log(this.value);
console.log(name);
console.log(age);
}
bar.prototype.friend = 'frank';
var bindFoo = bar.bind(foo, 'xxiang');
var obj = new bindFoo('22');
// undefined
// xxiang
// 22
console.log(obj.habit) // exercise
console.log(obj.friend) // frank
模拟实现
Function.prototype.bind = function (context) {
// 判断是否为函数,否则抛出一个错误。
if (typeof this !== "function") {
throw new Error("context is not function");
}
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
var fNOP = function () {};
var fBound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
// 用 apply 来实现的好处是直接可以用类数组(arguments)作参数。
// 判断是否是 new 构造函数调用。
return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
}
// 借助空函数做中转。
// 如果写成 fBound.prototype = this.prototype,共享一个对象不好。
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
// 返回函数是因为可能需要执行函数的返回结果。
return fBound;
}
参考:
[1] JavaScript深入之bind的模拟实现
[2] MDN