2012-03-08 53 views
1

我想創建一個JavaScript對象,我可以調用任何方法,而不必定義它們。理想情況下,我可以把它稱爲一個函數,它會調用一個函數,我用定義的函數名稱作爲其參數。如何創建一個可以調用任何方法的JS對象?

,所以我會定義一個對象與callMethod(methodName)方法,當我叫

thisObject.doAThing(); 

它會叫thisObject.callMethod("doAThing");

這可能在JavaScript?

回答

1

不,這是不可能的。如果一個JavaScript對象沒有屬性,那麼你不能將未定義的值作爲一個方法。

0

原始帖子(不好意思,應該問在Q評論這個問題):

我無法看到這一點。如果callMethod可以訪問某個地方的「doAThing」方法,爲什麼不能將其插入到對象的實例化中,或者何時callMethod的源文件添加了新方法?

不想辜負你。試圖看看是否可能在呼叫/應用/原型範例的瘋狂瘋狂世界的某個地方,它可能適應你希望以其他方式實現的目標。

編輯此評論後說:

我想創建一個代理對象,代理給另一個 對象的調用。 - msfeldstein

好吧,原型可能是答案,因爲它基本上確實充當對象本身沒有的方法的回退。每個函數都有一個原型屬性,它基本上只是一個普通的香草對象。當函數用作構造函數時,分配給構造函數原型的方法和屬性成爲構造函數實例的後備,當你調用他們沒有的屬性時。您可以將屬性添加到該原型對象,並且它們將可以有效地用於已創建的實例。所以,我在關聯對象的情況下想這樣的:

//A js constructor is just a function you intend to invoke with the 'new' keyword 
//use of 'this.property' will make that property public in the instance 
//var effectively makes it private 
//Constructors funcs differ from classes in that they don't auto-handle inheritance down to other constructors. You have to come up with a prototype merging scheme to do that. 

function MyFacadeConstructor(){ //expected args are objects to associate 
     var i = arguments.length; //arguments is a collection of args all funcs have 
     while(i--){ 
      var thisObj = arguments[i]; 
      associateObjMethods(thisObj); 
     } 

     //makes it public method but allows function hoisting internally 
     this.associateObjMethods = associateObjMethods; 
     function associateObjMethods(obj){ 
      for(var x in obj){ 
       if(obj[x].constructor.name === 'Function'){ //normalize for <= IE8 
        MyFacadeConstructor.prototype[x] = obj[x]; 
        //or if we literally want the other method firing in its original context 
        //MyFacadeConstructor.prototype[x] = function(arg){ obj[x](arg); } 
        //Not sure how you would pass same number of arguments dynamically 
        //But I believe it's possible 
        //A workaround would be to always pass/assume one arg 
        //and use object literals when multiple are needed 
       } 
      } 
     } 
    } 

    function FirstNameAnnouncer(){ 
     this.alertFirst = function(){ 
      alert('Erik'); 
     } 
    } 

    var fNamer = new FirstNameAnnouncer(); 

    var newFacade = new MyFacadeConstructor(fNamer); 

    //newFacade.alertFirst should work now; 
    newFacade.alertFirst(); 

    //but we can also associate after the fact 

    function LastNameAnnouncer(){ 
     this.alertLast = function(){ alert('Reppen'); } 
    } 

    var lNamer = new LastNameAnnouncer(); 

    newFacade.associateObjMethods(lNamer); 

    //now newFacade.alertLast should work 
    newFacade.alertLast(); 

現在,如果你想調用對象的上下文關係,我會建議一個事件驅動接口,這是一件好事JS很非常適合。讓我知道是否有任何方面你正在尋找的門面方法,我沒有在這裏實現。

+0

這是[Objective-C](http://www.cocoadev.com/index.pl?MessageForwarding)中的常見模式,它允許創建功能強大的[facade](http://en.wikipedia.org/wiki/Facade_pattern) – user123444555621 2012-03-08 07:56:15

+0

這個callMethod函數在Objective-C方法中尋找它所需的方法在哪裏?對象是否在執行調用事項,還是關於來自被調用對象關聯或聚合對象的共享方法池?我想你可以走幾條路。 – 2012-03-09 01:53:57

+0

我想創建一個將其調用委託給另一個對象的代理對象。 – msfeldstein 2012-03-09 07:51:42

1

在Firefox至少,你可以用魔術方法__noSuchMethod__來實現自己的目標:

var o = {} 
o.__noSuchMethod__ = function(id, args) { alert(id + args); } 
o.foo(2,3) //will alert "foo" and "2,3" 

請注意,這不是標準,正在考慮搬遷,所以it will not be added to V8

相關問題