0

如果我get使用defineProperty

Object.defineProperty(Object.prototype,'parent',{
    get:function(){return this.parentNode}
});

我可以这样称呼它:document.body.parent,然后就可以了。

当我value使用defineProperty

Object.defineProperty(Object.prototype,'parent',{
    value:function(x){
        var temp=this.parentNode;
        for(var i=1;i<x;i++){temp=temp.parentNode};
        return temp
    }
});

我可以这样称呼它:document.getElementsByName("newtag").parent(2),意思是找到newtag的父节点的父节点。

但是当我把它们放在一起时,它说Uncaught TypeError: Invalid property. A property cannot both have accessors and be writable or have a value

我怎样才能做到这一点,以便我可以同时调用它,.parent& .parent(n)

没有 jQuery

4

2 回答 2

0

不,不幸的是你不能。相反,您可以创建一个稍微不同的函数,默认情况下返回第一个 parentNode(如果没有指定参数),否则它会计算 n 个父节点。

Object.prototype.parent = function (n) {
    if (!this.hasOwnProperty('parentNode')) return null;
    if (!n || n === 1) return this.parentNode;
    var temp = this.parentNode;
    for (var i = 1; i < n; i++)
        temp = temp.parentNode;
    return temp;
};

一些注意事项:首先,您应该检查 Object 是否具有属性 parentNode,否则脚本将引发异常。我用过hasOwnProperty,但如果你只是扩展,你可以删除那条线HTMLElement

此外,如果 n 为 0 或 1,或者未定义,它将返回元素的 parentNode。用作element.parent()element.parent(2)

于 2013-06-16T15:38:08.893 回答
0

MDN描述了错误的原因

对象中存在的属性描述符有两种主要形式:数据描述符和访问器描述符。数据描述符是具有值的属性,它可能是可写的,也可能是不可写的。访问器描述符是由一对 getter-setter函数描述的属性。描述符必须是这两种风格之一;它不能两者兼而有之。

这是有原因的:你想要的方式是模棱两可的:如果parent()是一个函数,那么parent会返回那个函数getter?

不要更改您不拥有的对象。这样的代码是不可维护的:如果有人Object.prototype.parent()在他的库中定义自己的,你就不能使用它。在使用任何代码之前,您需要跟踪更改的内容。这与从头开始编写所有内容一样努力。

Object.prototype更改是特别糟糕的主意:通过原型,您将parent()函数添加到每个数组、JSON 对象、webAPI对象......他们没有parentNode,所以该函数对他们来说完全没用,这只是一个性能负担。

前两段是我们有Object.defineProperty和没有的原因Object.prototype.defineProperty。请注意,如果是这样,您可以myAPI.defineproperty(...)在下面的代码中进行编码,该代码更短,但是......性能和设计...... schrecklich。

你可以编写这样的代码

var myAPI = {
  node: document.body,
  level: 1
};

Object.defineProperty(MyAPI,'parent',{
    get:function(){
        var temp=MyAPI.node.parentNode;
        // some sanity check should be performed here
        for(var i=1;i<MyAPI.level;i++){temp=temp.parentNode};
        return temp;
    }
});

myAPI.node = document.getElementById("myNode");
myAPI.level = 2;
var grandFather = myAPI.parent; // actually returns the grandparent

但我怀疑它会有用。

于 2015-11-08T21:34:05.857 回答