javascript 軟化繫結
阿新 • • 發佈:2018-11-25
1. 被忽略的this
如果你傳遞null或者undefined作為call,apply,或bind的this繫結引數,那麼這些值會被忽略掉,取而代之的是預設繫結規則將適用於這個呼叫。在嚴格模式下(被調函式內部使用strict模式), this等於undefined, 在非嚴格模式下,this指向global物件(在瀏覽器中是window)。
2. 防止this繫結退回到預設繫結的措施
2.1 空物件 {}
2.2 DMZ物件 Object.create(null)
如果想讓使用的函式不關心this,可以傳遞一個空物件作為thisArgs, 但空物件的原型指向Object.prototype,在Object.prototype上新增的任何屬性都會影響到大多數物件,因為絕大多數物件原型鏈終端都是Object.prototype,為了隔離這個副作用,可以傳遞一個完全為空的物件Object.create(null), 任何對this的隱藏或意外的使用將會被限制在這個空物件中。
2.3 軟化繫結
防止退回到預設繫結,意外的修改global物件,同時保持函式可以通過隱含繫結或顯式繫結來手動繫結this。
if(!Function.prototype.softBind) { Function.prototype.softBind = function (obj) { var fn = this; curried = [].slice.call(arguments,1), bound = function bound() { return fn.apply( (!this || (typeof window !== "undefined" && this === window) || ( typeof global !== "undefined" && this === global) ) ? obj : this, curried.concat.apply(curried,arguments) ); }; bound.prototype = Object.create(fn.prototype); return bound; }; } function foo() { console.log("name:" + this.name); } var obj = {name:"obj"}, obj2 = {name:"obj2"}, obj3 = {name:"obj3"}; var fooOBJ = foo.softBind(obj); fooOBJ();//name: obj obj2.foo = foo.softBind(obj); obj2.foo();//name: obj2 fooOBJ.call(obj3); setTimeout(obj2.foo,10);//name: obj 退回到軟繫結