2012-12-17 96 views
0

我定義了一個Node的原型函數'isElement',並且我想使它像'div.isElement'返回'true'一樣工作。重定義函數的'toString'和'valueOf'

<div id="dom1">someText 
    <p>This is p1 of <span class="bold">dom1</span></p> 
</div> 

Node.prototype.isElement = (function(){ 
    var result; 
    var fn = function(){ 
     console.log(obj); 
     result = (this.nodeType == 1 ? true : false); 
     return result; 
    }; 
    fn.toString = fn.valueOf = function(){ 
     return result; 
    }; 
    return fn; 
})(); 

var dom1 = document.getElementById('dom1'); 
dom1.isElement(); //true 
dom1.isElement; //true 

如果 'DOM1' 永遠不會調用函數 'isElement()',然後 'dom1.isElement' 迴歸 '不確定'。我明白爲什麼它返回'未定義',但我想知道如何在'isElement()'永遠不會被調用時返回'true'或'false'。

我只是想用它像:

if(dom1.isElement){//do something} 

,但不喜歡:

if(dom1.isElement()){//do something} 

等待解答,謝謝。

+1

不可能的,因爲我知道,除非你改變'isElement'是一個布爾值屬性,並修改所有會影響這個'isElement'布爾值的方法。經歷這個麻煩真的沒有意義。開銷可以忽略不計。只需使用它作爲方法調用即可。 (我特指最後一部分) – Raekye

+2

正如一般說明,擴展DOM並不被認爲是一個好主意。順便說一下,'if(dom1.isElement)'總是會**評估爲'true',因爲它是一個(函數)對象(不管你讓'toString'返回什麼)。 –

+0

您假定DOM元素實現原型繼承,並且您可以修改構造函數的原型。既不需要瀏覽器(或一般的主機環境)來實現原型繼承,有的則不需要。 – RobG

回答

0

您可以添加與你的函數的獲取方法的屬性:

Object.defineProperty(Node.prototype, "isElement", { 
    get: function() { 
     var result = this.nodeType == 1; 
     return result; 
    } 
}); 
+0

想必您只對基於Gecko的瀏覽器感興趣。 – RobG

+0

@RobG其實,所有ES-5兼容的瀏覽器都應該有這個。 –

+0

請注意'結果'是全球性的。你可能只想'返回this.nodeType === 1;'。 –

1

正如在評論中提到的,JavaScript語言不保證該DOM實現提供了標準的JS對象設施。這就是說,如果你確定你的環境總是支持這些,那麼在這種情況下調用getter,實際上你可以編寫一個函數,只要請求一個特定的屬性值就會調用它。

參考MDN的細節:

Node.prototype.__defineGetter__('isElement', 
    function() { return this.nodeType === 1; }); 

測試它與您的瀏覽器在http://jsfiddle.net/L5hBq/

+0

+1,但不是該策略的粉絲。它將函數調用僞裝成屬性訪問。當用戶執行'dom1.isElement = true;'時會發生什麼?對於我來說,getter和setter應該用來維護狀態或依賴關係,或者用於同步數據,所以最好使屬性只讀並拋出。 – RobG

+0

我並不過分熱衷於自己 - 警惕空頭。設置'dom1.isElement'不會導致問題(至少在Chrome上),因爲我沒有定義setter。更新小提琴來測試這個:http://jsfiddle.net/L5hBq/1 – HBP

+0

defineGetter是非標準的和不推薦使用的。 –