过去一周我一直在努力学习关于js继承的知识,并且遇到了john resig的简单js继承脚本。在测试代码时,一切都很顺利,直到我试图迭代我的一个扩展对象。这是代码:
var Person = Class.create({
init : function(sex, devStage) {
this.sex = sex;
this.devStage = devStage || "newBorn";
},
Sex : function(val) {
if (val) { this.sex = val }
else { return this.sex; }
},
DevStage : function(val) {
if (val) { this.devStage = val; }
else { return this.devStage; }
}
});
var person = new Person("male");
var Mike = Person.extend({
init : function(sex, devStage, name, age) {
this._super(sex, devStage);
this.name = name;
this.age = age;
},
DevStage : function(val) {
if (val) { this._super(val); }
else { return this._super(); }
},
Name : function(val) {
if (val) { this.name = val; }
else { return this.name; }
},
Age : function(val) {
if (val) { this.age = val; }
else { return this.age; }
}
});
var mike = new Mike("male", "adult", "Mike", 38);
for (var k in mike) {
if (mike.hasOwnProperty(k)) { console.log("mike.hasOwnProperty(k) = " + k); }
} //only "sex", "devStage", "name" and "age" show up as properties in firebug's console
我期待mike对象上存在“DevStage”,“Name”和“Age”函数属性,但似乎将它们放到每个对象的实例上的唯一属性是那些被发送到init函数的属性。其他属性在对象的原型上,并且工作正常,我只是无法使用hasOwnProperty方法找到它们。我已经阅读了resig博客文章发布时的大部分评论,但我找不到与此问题相关的任何内容。
我的问题是这是否正常?如果在对象之间进行一些属性检查,我可以看到这将成为问题的时间。这对我来说似乎是一种有效的担忧吗?虽然不是全新的js,但我当然没有经验丰富的专业人士,所以我对目前情况的任何反馈都会非常感激。
答案 0 :(得分:1)
是的,这很正常。属性DevStage
,Name
,Age
和init
附加到Mike
的原型,新对象{{ 1}} 仅指向 - 使用mike
创建对象时,不会复制属性。
因此,new Mike()
没有“自己的属性”这些属性 - 只有查看mike
的内部原型属性才能访问它们(这是什么访问属性时,JS引擎会自动执行:mike
)。某些JS引擎(如Chrome)将此内部原型属性公开为mike.DevStage
,您可以检查它。
这是对__proto__
如何在内部表示的描述:
mike
如果从循环中删除mike = {
__proto__: { // Internal pointer to the prototype, for Mike
init: function () {},
DevStage: function () {},
Name: function () {},
Age: function () {},
__proto__: { // The prototype's prototype, for Person
init: function () {},
Sex: function () {},
DevStage: function () {}
// Ultimately, the prototype will point to Object.prototype
__proto__: {...}
}
},
// Own properties
name: ...,
age: ...,
sex: ...,
devStage: ...
}
条件,那么您也会看到其他属性。