2012-03-14 21 views
1

我正在學習更多關於JavaScript OOP的知識,通過滾動我自己的console.log變體並添加一些我想要的功能。JavaScript對象中的任意方法名稱

到目前爲止,我有

debug = { 
     consoleAvailable : (typeof console == "object"), 
     reportToConsole : 0, 
     list   : [], 
     setReporting : function(level){ 
          this.reportToConsole = level; 
          return true; 
         }, 
     log    : function(){ 
          if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function") console.log.apply(console, this.log.arguments); 
          this.list.push({'type':'log', 'msg':this.log.arguments}); 
          return true; 
         }, 
}; 

這是所有工作很好,但我不希望有列出所有的日誌,錯誤,警告等功能。相反,我希望能夠只輸入debug。[something]和一個函數來解釋[something]並以與我有日誌函數工作相同的方式執行它。

這甚至可能嗎?如果是這樣,我該怎麼辦呢?

以下是我希望能夠做的一些例子。

debug.setReporting(1); //yes, I want to print to console 

debug.log('foo', 'bar', 'baz'); //arbitrary number of arguments (this is already working) 
debug.error('qux'); //function I haven't named, but there is a console.error function 
debug.arbitraryName([1, 2, 3]); //no function for console.arbitraryName (ideally it would just console.log the argument(s) 

編輯

好了,它看起來像@Rob W公司的方法是要走的路,但我有麻煩實施。似乎我沒有正確或類似地傳遞函數的名稱。我這裏有一個小提琴顯示問題http://jsfiddle.net/xiphiaz/mxF4m/

結論

它看起來像有太多的瀏覽器怪癖獲得無需編寫瀏覽器特定的代碼真正通用的調試器,所以不是我剛纔列舉我最常用的日誌功能(日誌,警告和錯誤)。這讓我可以選擇進一步自定義這些功能的結果。

結果:

debug = { 
    consoleAvailable : (typeof console == "object"), 
    reportToConsole : 0, 
    list   : [], 
    setReporting : function(level){ 
         this.reportToConsole = level; 
         return true; 
        }, 
    log    : function(){ 
         if (this.reportToConsole>0 && this.consoleAvailable && typeof console.log=="function") console.log.apply(console, this.log.arguments); 
         this.list.push({type:'log', msg:this.log.arguments}); 
         return true; 
        }, 
    warn   : function(){ 
         if (this.reportToConsole>0 && this.consoleAvailable && typeof console.warn=="function") console.warn.apply(console, this.warn.arguments); 
         this.list.push({type:'warn', msg:this.warn.arguments}); 
         return true; 
        }, 
    error   : function(){ 
         if (this.reportToConsole>0 && this.consoleAvailable && typeof console.error=="function") console.error.apply(console, this.error.arguments); 
         this.list.push({type:'error', msg:this.error.arguments}); 
         return true; 
        } 
}; 

debug.setReporting(1); 

debug.log('foo', 'bar', 'baz'); 
debug.error('qux'); 
debug.warn({test:"warning"}); 
console.log(debug.list); 
+0

請注意,在IE中,console.log等東西不是函數,因此沒有'apply'方法來傳遞可變數量的參數。你必須對不同長度的單獨調用進行硬編碼:'a = arguments; if(a.length == 1){console.log(a [0])} if(arguments.length == 2){console.log(a [0],a [1]}' – hugomg 2012-03-14 22:26:26

+0

但是我在做在嘗試「apply」之前檢查它是否是函數,這是不夠的嗎? – 2012-03-14 22:28:00

+0

啊,沒關係然後 – hugomg 2012-03-14 22:35:09

回答

1

可以使用Object.getOwnProprtyNames方法得到的所有屬性(包括非可枚舉的)的陣列。然後,通過它枚舉,並檢查console[key]是否是一個函數。如果是,則使用該方法擴展自己的對象。

Object.getOwnPropertyNames(console) 

至於你的最後quesion,有一個非標準__noSuchMethod__方法,攔截未定義函數的調用。

我強烈建議使用我的第一個建議的方法,因爲console方法不會奇蹟般地變大。它也使調試更容易。

+0

問題在於我希望函數能夠執行,而不管屬性函數是否存在(該函數需要將參數添加到dialog.list數組中)。我只想知道console.functions是否存在,這樣我就可以調用它而不會出現錯誤。 – 2012-03-14 21:54:52

+0

對不起,我誤讀了。 '__noSuchMethod__'似乎是我以前的樣子,但它是一個真正的失望,它不是標準。 Kinda擊敗了製作跨瀏覽器記錄器的目的:( – 2012-03-14 22:06:20

+0

@ZakHenry我明白你的意圖,我的第一個解決方案是最簡單的方法來完成這個任務,它檢測每個現有的'console。*'方法,它可以添加到你的命名空間,沒有通用的getter方法 – 2012-03-14 22:10:05