JavaScript中硬绑定与软绑定详解
JS中硬绑定这类体式格局能够把this强迫绑定到指定的对象(除了运用new时),防备函数调用时运用默许绑定划定规矩(非严厉形式下全局对象-window
| global,严厉形式下undefined)。硬绑定会大大下降函数的灵活性,运用硬绑定以后就没法运用像“隐式绑定”或“显现绑定”来修正this。
假如能够给默许绑定指定一个全局对象和undefined不测的值,那就能够完成和“硬绑定”雷同的结果,同时保存“隐式绑定”或“显现绑定”修正this的才能。
// hard binding
if(!Function.prototype._hardBind) {
Function.prototype._hardBind = function(oThis) {
if(typeof this !== 'function') {
throw new TypeError('Function.prototype.softBind - what is trying to be bound is not callable.');
}
var aArgs = [].slice.call(arguments, 1);
var fToBind = this;
var fNOP = function() {};
var fToBound = function() {
return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat([].slice.call(arguments)));
};
if(this.prototype) {
fNOP.prototype = this.prototype;
}
fToBond.prototype = new fNOP();
return fToBond;
};
}
// test code
function foo() {
console.log('name: ' + this.name);
}
var obj1 = {name: 'obj1'};
var obj2 = {name: 'obj2'};
var obj3 = {name: 'obj3'};
var _foo = foo._hardBind(obj1);
_foo(); // 'name: obj1'
obj2.foo = foo._hardBind(obj1);
obj2.foo(); // 'name: obj1'
_foo.call(obj3); // 'name: 'obj1'
setTimeout(obj2.foo, 100); // 'name: obj1'
// soft binding
if(!Function.prototype._softBind) {
Function.prototype._softBind = function(oThis) {
if(typeof this !== 'function') {
throw new TypeError('Function.prototype.softBind - what is trying to be bound is not callable.');
}
var aArgs = [].slice.call(arguments, 1);
var fToBind = this;
var fToBound = function() {
return fToBind.apply((!this || (this === (window || global))) ? oThis : this, aArgs.concat([].slice.call(arguments)));
};
fToBound.prototype = Object.create(fToBind.prototype);
return fToBound;
};
}
// test code
function foo() {
console.log('name: ' + this.name);
}
var obj1 = {name: 'obj1'};
var obj2 = {name: 'obj2'};
var obj3 = {name: 'obj3'};
var _foo = foo._softBind(obj1);
_foo(); // 'name: obj1'
obj2.foo = foo._softBind(obj1);
obj2.foo(); // 'name: obj2'
_foo.call(obj3); // 'name: obj3'
setTimeout(obj2.foo, 100); // 'name: obj1'
能够看到,软绑定版本的foo()能够手动将this绑定到obj2或许obj3上,但假如运用默许绑定划定规矩,则会将this绑定到oThis。