【问题标题】:Using Function.prototype.call as a callback使用 Function.prototype.call 作为回调
【发布时间】:2012-11-04 03:20:00
【问题描述】:

我在 Google Chrome 控制台中尝试了以下操作:

> function t1(f) { return f(1); }
> function t2() { return this+1; }
> t1(t2.call)
TypeError: object is not a function

为什么这不起作用?有没有办法定义一个函数来代替 Function.prototype.call 在这里可以工作?

【问题讨论】:

    标签: javascript function callback


    【解决方案1】:

    它不起作用,因为当你传递t2.call 时,你实际上只是传递了.call。换句话说,它不记得传递它的对象。


    要完成您想要的,您可以使用.bind()

    t1(t2.call.bind(t2))
    

    这会将t2 函数绑定为.callthis 值,这意味着您将调用.call,就好像您已经这样做了:

    t2.call
    

    ...这就是你想要的。


    .bind 方法在 IE8 及更低版本以及其他一些较旧的浏览器中不受支持,但在这些情况下您可以实现几乎完整的填充程序。


    仅供参考,如果你需要这个很多,你可以绑定.call作为.bind的调用上下文来缩短一点。

    var callBind = Function.prototype.bind.bind(Function.prototype.call);
    

    所以现在你有了一个.bind() 函数,其中.call() 绑定为它的调用上下文。当您调用它时,就好像您正在这样做:

    .call.bind(/* the function */)
    

    所以callBind() 将返回一个函数,将the function 绑定为.call 的调用上下文,就像我们在上面所做的那样。所以你会这样使用它:

    t1(callBind(t2))
    

    【讨论】:

    • "它不起作用,因为当你传递 t2.call 时,你实际上只是传递了 .call。换句话说,它不记得传递它的对象。 "如果可能的话,你能多解释一下吗?我不太明白为什么它不记得这个对象。
    • @Ray: .call 只是对象的一个​​属性。对象和函数之间的唯一关系是函数被赋值给属性。当您将t1.call 传递给另一个函数时,您从t1 对象中检索该函数,但只传递函数,而不是对象。就好像我递给你一些东西,而你却把它拿在了某个地方。我一放手,我和那个东西的关系就断了,那个东西和我没有联系。
    • 啊,好吧,我想我明白了。这就像一个普通的对象/属性说o ={name: "foo"}。然后你打电话给f(o.name),它只是那个属性.name,发送时没有o的附件/引用......是吗?
    【解决方案2】:

    为什么要以艰难的方式做事?您不能将回调函数t2 发送到t1 并在t1 中使用call() 吗?

    function t1(f) { 
        return f.call(1); 
    }
    
    function t2() { 
        return this+1; 
    }
    
    t1(t2);
    

    【讨论】:

    • 嗯,这真的比其他任何东西都更适合个人熏陶。不过感谢您的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 2023-03-09
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    相关资源
    最近更新 更多