// 这是MDN提供的一种bind(..)实现,代码进行了排版
// 代码会判断硬绑定函数是否被new调用,如果是的话就会使用新创建的this
// 替换硬绑定的this
if (!Function.prototype.bind1) {
Function.prototype.bind1 = function (oThis) {
// oThis = null;
if (typeof this !== "function") {
// 与 ECMAScript 5 最接近的
// 内部 IsCallable 函数
throw new TypeError(
"Function.proptotype.bind - what is trying " +
"to be bound is not callable"
);
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this, // foo函数体
fNOP = function () {},
fBound = function () {
// this instanceof fNOP === true时,说明返回的fBound被当做new的构造函数调用
return fToBind.apply(
(
this instanceof fNOP ? this : oThis
),
aArgs.concat(
Array.prototype.slice.call(arguments)
)
);
};
// 维护原型关系
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
// 下行的代码使fBound.prototype是fNOP的实例,因此
// 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,
// 新对象的__proto__就是fNOP的实例
fBound.prototype = new fNOP();
return fBound;
}
}
function foo(p1, p2) {
this.val = p1 + p2;
}
// 之所以使用null时因为在本例中我们并不关心硬绑定的this是什么
// 反正使用new时this会被修改
var bar = foo.bind1(null, 'p1');
var baz = new bar('p2');
console.log(baz.val); // "p1p2"