【问题标题】:Delegate Javascript Functions委托 Javascript 函数
【发布时间】:2012-07-09 11:22:49
【问题描述】:

作为一个显着简化的场景,假设我有 2 个 Javascript 对象定义如下:

var ClassA = Class.extend({
    'say': function(message) {
        console.log(message);
    }

    ... // some more methods ...
});

var ClassB = Class.extend({
    init: function(obj) {
        this._target = obj;
    }
});

我想在 Javascript 中有某种机制可以使我们能够做到以下技巧:

var b = new ClassB( new ClassA() );
b.say("hello");

我想找到一种方法来检测是否有一个方法调用ClassB,并且该方法在ClassB中没有定义,那么我可以自动将方法调用转发到ClassA上,这是ClassB中的成员变量。

在实际场景中,ClassA 是一个作为 brwoser 插件实现的对象,并使用 <object> 标签插入到网页中。它的方法是用 C++ 代码实现的,所以我无法从它的原型中分辨出它的方法,并事先将其插入到ClassB 的原型中。

我想使用该技术来创建一个原生 Javascript 对象,该对象具有 ClassA 界面的窄化版本。有什么办法可以做到吗?

【问题讨论】:

  • 听起来您实际上希望 ClassB 继承 ClassA 的功能。反正Class.extend({})没有原生JS机制,你用的是什么框架?
  • @pixelistik 我相信他在Object 中添加了一个扩展方法。
  • @pixelistik 在项目中我使用的是 JS.Class (jsclass.jcoglan.com),而在这个示例中我使用的是 John Resig 的简单继承 (ejohn.org/blog/simple-javascript-inheritance)。不过应该没有太大区别。

标签: javascript


【解决方案1】:

我认为没有快速的跨浏览器解决方案。

如果你只需要 Firefox,那么使用__noSuchMethod__

请看这里:is-there-such-a-thing-as-a-catch-all-key-for-a-javascript-object 在这里:javascript-getter-for-all-properties

否则,我会尝试这样的事情:

var b = new ClassB( new ClassA() );

// functionToCall is a string containing the function name
function callOnB(functionToCall) {
    if(typeof b[functionToCall] === function) {
        b[functionToCall]();
    } else {
        b._target[functionToCall](); // otherwise, try calling on A
    }
}

这是使用Square Bracket Notation where

b.say('hello')

相同
b['say']('hello')

当然,您可能应该扩展它以接受参数:

function callOnB(functionToCall, listOfArguments) {...}

【讨论】:

  • 顺便说一句,如果您像这样访问 b[functionName],某些类型的恶意浏览器对象(如 IE xml 内容)可能会出现类型错误,或者可能会将“object”返回给 typeof。您可能只想进行 (functionToCall in b) 测试。
  • 另外,由于我们谈论的是邪恶的插件对象,它们可能没有调用或应用方法,因此您可能需要执行类似switch(args.length){ case 1: return f(a) case 2: return f(a,b); ... } 的操作来手动处理多个参数。
【解决方案2】:

感谢 jfrej 关于 noSunchMethod 的提示,我对它进行了更多研究,结果发现我需要的是与 Harmony Proxies(herehere)完全匹配。可以在http://jsbin.com/ucupe4/edit#source 找到一个示例

另一个相关帖子:http://dailyjs.com/2010/03/12/nosuchmethod/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    相关资源
    最近更新 更多