如何获取原型链的属性而不是对象本身的属性?

时间:2016-06-17 12:52:24

标签: javascript

我有一个这样的对象:

var Animal = function() { };
Animal.prototype.size = 'small';
Animal.prototype.height = '50';

var Mammal = function() { };
Mammal.prototype = new Animal();
Mammal.prototype.name = 'rabbit';
Mammal.prototype.nickname = 'aaa';

var Rabbit = function(nickname) {
    this.nickname = nickname;
};
Rabbit.prototype = new Mammal();
Rabbit.prototype.name = 'bbbbbbb';

var myRabbit = new Rabbit('Cutie'); 

对于这个对象,我想把它的属性分成两组:它自己的属性和从它的原型链继承的属性。所以我这样做:

function getObj(obj){
    var ownKeys = Object.keys(obj); // it's ok, I get 'nickname'

    var protoKeys = [];
    var props = Object.getOwnPropertyNames(obj); // here I can't get all of the properties
    console.log(props);
} 

问题是在几种情况下属性名称是相同的。而且由于这个原因我无法获得原型链的所有属性(名称,名称,昵称,大小,高度)。

有没有办法获得所有原型链属性?或者他们的名字必须是唯一的? 非常感谢提前!

4 个答案:

答案 0 :(得分:1)

BlurMyTextbox

希望这能帮到你!

答案 1 :(得分:1)

使用for..in循环迭代对象属性,使用Object.hasOwnProperty方法过滤掉所有“本地”对象属性:

var myRabbit = new Rabbit('Cutie');
var inherited_props = [];
for (var i in myRabbit) {
    if (!myRabbit.hasOwnProperty(i)) inherited_props.push(i);
}

console.log(inherited_props); // ["name", "size", "height"]

至于检索原型的对象属性,该属性与初始对象的现有属性同名 - 请参阅我的“上一个”答案:How do I retrieve a property from a prototype's object that is inside a constructor function

答案 2 :(得分:1)

var props = [];
var proto = obj;

// We go through a chain of prototypes    
while(proto !== null) {
    if (proto!==null) {
        var tmp = {};
        // For each prototype collect property values
        Object.keys(proto).forEach( function(p) {
            tmp[p] = proto[p];
        });
        props.push(tmp);
        proto = proto.__proto__;
    }
}

console.log(props);

答案 3 :(得分:1)

如果要列出对象obj继承的可枚举属性,可以使用

var props = [],
    proto = Object.getPrototypeOf(obj);
for(var prop in proto)
  props.push(prop);

通常,如果obj是构造函数Constr的实例,您也可以获得[[Prototype]]之类的

var proto = Constr.prototype;
var proto = obj.constructor.prototype;

如果您想获得不可枚举的属性,则必须手动迭代原型链:

var props = new Set(), // Use a set to avoid repetitions
    proto = obj;
while(proto = Object.getPrototypeOf(proto))
  for(var prop of Object.getOwnPropertyNames(proto))
    props.add(prop);

如果您不想避免重复,请使用数组而不是集合:

var props = [],
    proto = obj;
while(proto = Object.getPrototypeOf(proto))
  props.push.apply(props, Object.getOwnPropertyNames(proto));

或者没有不可枚举的重复:

var props = [],
    proto = obj;
while(proto = Object.getPrototypeOf(proto))
  props.push.apply(props, Object.keys(proto));