【隨筆】JavaScript bind()的初步手寫實現及使用
阿新 • • 發佈:2021-05-13
本文程式碼參考的是《前端開發核心知識進階 從夯實基礎到突破瓶頸》——作者 侯策
/* 初版,如果對返回的繫結函式傳參,存在丟失引數的問題 */ Function.prototype.badBindFn = function (context) { var me = this var argsArray = Array.prototype.slice.call(arguments) /* 返回繫結函式 */ return function () { return me.apply(context, argsArray.slice(1)) } } /* 改進版,如果對返回的繫結函式傳參,也會拼接到bind()的引數陣列中 */ Function.prototype.bindFn = function (context) { var meFn = this var args = Array.prototype.slice.call(arguments, 1) /* 返回繫結函式 */ return function () { var innerArgs = Array.prototype.slice.call(arguments) var finalArgs = args.concat(innerArgs) return meFn.apply(context, finalArgs) } } function foo(paramsA, paramsB) { this.a = paramsA this.b = paramsB } const objZhuGe = {} const objWang = {} window.onload = function () { var badFooFunc = foo.badBindFn(objZhuGe, '諸葛亮') badFooFunc("諸葛孔明") console.log(objZhuGe) //諸葛亮 undefined var fooFunc = foo.bindFn(objWang, '王朗') fooFunc('王司徒') console.log(objWang) //王朗 王司徒 }
執行結果:
第三個版本個人領悟能力低下,暫時啃不動,先貼在下面:
Function.prototype.bind = function(context) { var me = this var args = Array.prototype.slice.call(arguments, 1) var F = function(){} F.prototype = this.prototype //??? var bound = function(){ var innerArgs = Array.prototype.slice.call(arguments) var finalArgs = args.concat(innerArgs) return me.apply(this instance of F ? this : context || this, finalArgs) //??? } bound.prototype = new F() //???? return bound }
在MDN上也列舉了polyfill兩種實現方式,點選這裡可以參考