为什么当我在这个JavaScript对象上使用反射时,我看不到它的原型对象中定义的属性?

时间:2015-12-30 11:05:31

标签: javascript jquery javascript-objects prototypal-inheritance

我是JavaScript的新手,我实际上正在研究教程中的反射概念。

所以我有以下代码:

final = {}
for k in dict1[0].Keys():
    final[k] = sum(x[k] for x in dict1)
return final

代码非常简洁,评论解释了它的作用。

所以我有一个通用的 person 对象提供 getFullName()方法,我还有 john 对象代表一个特定的人但是没有定义 getFullName()方法。

然后我这样做:

/* REFLECTION AND EXTEND:

REFLECTION: An object can look at itself listing and changing its properties and methods. So it means that a JavaScript object have the ability to look at its own properties and methods. We can use this feature of the JavaScript language to implement a very userful pattern called EXTEND.
*/


/* This is a generic person object that have 'firstname' and 'lastname' peropertiest setted on a 'Default' value. This generic person object provide also a getFullName() method that return the concatenation of the firstname and the lastname
*/
var person = {
    firstname: 'Default',
    lastname: 'Default',
    getFullName: function() {
        return this.firstname + ' ' + this.lastname;  
    }
}

/* This john object represent a specific person but do not provide the getFullName() method: */
var john = {
    firstname: 'John',
    lastname: 'Doe'
}

// don't do this EVER! for demo purposes only !!! 
/* This set the 'person' object on the proto variable of the john object. So from this john object I can also use the getFullName() method defined for the generic person object: */
john.__proto__ = person;


// Now, we are going to see an example of the use of reflection in JavaScript:


for (var prop in john) {            // Iterate on all the properties into the john object (prop is the current property during the iteration)
    if (john.hasOwnProperty(prop)) {
        // propo is the current property name and john[prop] is the related value of this property into the john object:
        console.log(prop + ': ' + john[prop]);      
    }
}

表示对象是 john 对象的原型,因此这意味着 john 对象继承自对象。所以我希望现在 john 对象可以访问 getFullName()方法。

然后我使用反射来迭代 john 对象,然后打印这些对象的所有属性。

我得到了这个结果:

john.__proto__ = person;

这在我看来很奇怪,因为我在教程中也可以看到,我希望看到这个属性:

firstname: John
lastname: Doe

因为现在我可以访问它了。

为什么我看不到它?我错过了什么?有什么问题?

2 个答案:

答案 0 :(得分:1)

正如可以看到 Juhana 已在评论中回答,但我想补充说明。

当你这样做时:

john.__proto__ = person;

我会说它连接两个对象,因为Object john具有person的原型。因此,john可以访问person对象中的所有可用属性。

这仍然不会将person对象的属性添加到对象john,但它们之间的连接按__proto__进行。所以,john仍然有自己的道具,它可以访问person对象中的方法。

这个条件:

if (john.hasOwnProperty(prop)) {

不会让它记录它原型的属性。

hasOwnProperty 限制了对迭代中当前对象的属性访问。

答案 1 :(得分:0)

首先,请避免使用 proto ,因为它在所有浏览器中都不相同。 现在 proto 为原型添加东西,即继承。 使用john.hasOwnProperty(prop)时只对自己的属性而不是对于继承的属性才是真的,这就是为什么getFullName