1. 程式人生 > 其它 >【隨筆】JavaScript bind()的初步手寫實現及使用

【隨筆】JavaScript bind()的初步手寫實現及使用

本文程式碼參考的是《前端開發核心知識進階 從夯實基礎到突破瓶頸》——作者 侯策

        /* 
            初版,如果對返回的繫結函式傳參,存在丟失引數的問題
        */
        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兩種實現方式,點選這裡可以參考