2012-07-09 60 views
3

作爲siginificantly簡化的情況下,說我有2個JavaScript對象定義如下:代表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界面的Narraw-ed版本。有什麼辦法可以做到這一點?

+1

聽起來像是你真的想ClassB的繼承ClassA的功能。無論如何,'Class.extend({})'不是原生的JS機制,你在使用什麼框架? – pixelistik 2012-07-09 11:52:02

+0

@pixelistik我相信他給Object添加了一個擴展方法。 – Joseph 2012-07-09 11:55:52

+0

@pixelistik在項目中我使用JS.Class(http://jsclass.jcoglan.com),而在這個例子中,我使用了John Resig的簡單繼承(http://ejohn.org/blog/simple-javascript-inheritance /)。不應該有太多的區別。 – 2012-07-10 01:54:54

回答

3

我不認爲有一個快速的跨瀏覽器解決方案。

如果你只需要火狐,然後用__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其中

b.say('hello') 

相同

b['say']('hello') 

當然,你或許應該擴大這一採取參數:

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

順便說一句,某些邪惡的瀏覽器對象(如IE瀏覽器xml的東西)可能會給類型錯誤,如果你像訪問b [functionName]那樣或可能返回「object」到typeof。您可能只想做一個'(functionToCall in b)'test來代替。 – hugomg 2012-07-09 12:44:52

+0

另外,由於我們正在討論邪惡的插件對象,他們可能沒有調用或應用方法,所以你可能需要做一些像'switch(args.length){case 1:return f(a)case 2:return f (A,b); ...}來手動處理多個參數。 – hugomg 2012-07-09 12:46:58