以下重写bind的函数结果为何不同

    1.第一种方式
        Function.prototype.bind = function() {
            var fn = this,
                args = Array.prototype.slice.call(arguments);
                object = args.shift();
            return function() {
                return fn.apply(object, args.concat(Array.prototype.slice.call(arguments)))
            }
        }
    2. 第二种方式
        Function.prototype.bind = function(oThis) {
            var fn = this,
                args = Array.prototype.slice.call(arguments,1);
            return function() {
                return fn.apply(oThis, args.concat(Array.prototype.slice.call(arguments)))
            }
        }
function foo() {
            return this.bar
        }
var a = foo.bind({bar: 2},1);
var b = a.bind({bar: 3},2);
var c = b.bind({bar: 4},3);
console.log(c())
//第一种方式是4
//第二种方式是2
阅读 2.3k
1 个回答

没遇到过多次bind的情况,我在当前chrome浏览器,直接用原生的bind方法情况下 ,得到的结果也是第二种方式的值:2,也就是说就算多次bind,绑定的this还是最初的那个bind。
第一种方式为什么会是4呢?
我看到你第一种方式的代码里,object变量前面一句语句居然没有用逗号而是用了分号,那么object就变成一个全局变量来用了,试想一下,最终都是要执行到 fn.apply(object, args.concat(Array.prototype.slice.call(arguments))),最终执行时,object作为一个全局变量,多次bind方法运行的时候,是不是object内容变了好多次?,最终object为{bar:4}.

假设object前面那一句用逗号来结尾,那么运行结果就是2了。也就没有所谓的第一种跟第二种不一样了。

至于第二种方式为什么多重bind不起作用,我截图来说一下:
clipboard.png
试想,当我执行c()的时候,其实接下来是执行 b.apply({bar:4}),对吧(后面参数的我先忽略了)
那么执行了这句,,我们知道一般fn.apply(obj),意义是fn里面涉及到this的时候指向obj。

但是,我们看看b,正常来说b()接下来应该是执行:

a.apply({bar:3})//同样参数那部分我忽略掉了

你看看,这一句执行语句,有涉及到b的this这一调用么?看不到有this的踪迹,也就是说,前面b.apply({bar:4})这个{bar:4}白绑定this了 ,因为你都没用到this……

接下来到a.apply的执行好理解了,最终是:

foo.apply({bar:2})

而我们再看看foo:

function foo() {
            return this.bar
        }

看,它终于用了this,那么这个时候this是绑定了{bar:2}的,所以,结果就是2了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题