2012-12-17 56 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是非标准的和不推荐使用的。 –