将defineProperty get和value一起使用

时间:2013-06-16 15:05:57

标签: javascript defineproperty

如果我将getdefineProperty

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

我可以称之为:document.body.parent,然后就可以了。

valuedefineProperty

一起使用时
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&amp; .parent(n)

没有jQuery

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

MDN描述了错误的原因

  

对象中存在的属性描述符有两种主要形式:数据   描述符和访问者描述符。 数据描述符是属性   具有值,可能是也可能不是可写的。 访问者   descriptor是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

但我怀疑它会有用。