JS中硬綁定這種方式能夠把this強制綁定到指定的對象(除了使用new時),防止函數調用時應用默認綁定規則(非嚴格模式下全局對象-window
| global,嚴格模式下undefined)。硬綁定會大大下降函數的靈活性,使用硬綁定以後就沒法使用像「隱式綁定」或「顯示綁定」來修改this。若是能夠給默認綁定指定一個全局對象和undefined意外的值,那就能夠實現和「硬綁定」相同的效果,同時保留「隱式綁定」或「顯示綁定」修改this的能力。app
// 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。
參考:You Dont Known JS函數