为什么当我在这个 JavaScript 对象上使用反射时,我看不到在其原型对象中定义的 属性?
Why when I use reflection on this JavaScript object I can't see a property defined in its prototype object?
我是 JavaScript 的新手,实际上我正在学习教程中的 反射 概念。
所以我有以下代码:
/* 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]);
}
}
代码非常简洁,注释解释了它的作用。
所以我有一个通用的 person 对象,它提供 getFullName() 方法,我还有 john 表示特定人但尚未定义 getFullName() 方法的对象。
然后我做:
john.__proto__ = person;
说 person 对象是 john 对象的原型,所以这意味着 john 对象继承自 person 对象。所以我希望现在 john 对象可以访问 getFullName() 方法。
然后我使用反射在 john 对象上进行迭代,并打印该对象的所有属性。
我得到这个结果:
firstname: John
lastname: Doe
这在我看来很奇怪,因为正如我在教程中也看到的那样,我希望也能看到这个 属性:
getFullName: function() {
return this.firstname + ' ' + this.lastname;
}
因为现在我可以访问它了。
为什么我看不到?我错过了什么?有什么问题?
可以看到Juhana已经在评论中回答了,但我想补充一下我的解释。
当你这样做时:
john.__proto__ = person;
我会说它连接了两个对象,因为 Object john
有 person
的原型。所以 john 可以访问 person 对象中的所有可用属性。
这仍然不会将人员对象的属性添加到对象 john,但它们之间根据 __proto__
具有连接。所以,john 仍然有自己的 props,它可以访问 person 对象中的方法。
这个条件:
if (john.hasOwnProperty(prop)) {
不允许它记录其原型的属性。
hasOwnProperty
限制 属性 访问迭代中的当前对象。
首先避免使用 proto 因为它在所有浏览器中都不一样。
现在 proto 向原型添加内容,即进行继承。
使用 john.hasOwnProperty(prop) 仅对自己的属性为真,对继承的属性不为真,这就是为什么 getFullName
我是 JavaScript 的新手,实际上我正在学习教程中的 反射 概念。
所以我有以下代码:
/* 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]);
}
}
代码非常简洁,注释解释了它的作用。
所以我有一个通用的 person 对象,它提供 getFullName() 方法,我还有 john 表示特定人但尚未定义 getFullName() 方法的对象。
然后我做:
john.__proto__ = person;
说 person 对象是 john 对象的原型,所以这意味着 john 对象继承自 person 对象。所以我希望现在 john 对象可以访问 getFullName() 方法。
然后我使用反射在 john 对象上进行迭代,并打印该对象的所有属性。
我得到这个结果:
firstname: John
lastname: Doe
这在我看来很奇怪,因为正如我在教程中也看到的那样,我希望也能看到这个 属性:
getFullName: function() {
return this.firstname + ' ' + this.lastname;
}
因为现在我可以访问它了。
为什么我看不到?我错过了什么?有什么问题?
可以看到Juhana已经在评论中回答了,但我想补充一下我的解释。
当你这样做时:
john.__proto__ = person;
我会说它连接了两个对象,因为 Object john
有 person
的原型。所以 john 可以访问 person 对象中的所有可用属性。
这仍然不会将人员对象的属性添加到对象 john,但它们之间根据 __proto__
具有连接。所以,john 仍然有自己的 props,它可以访问 person 对象中的方法。
这个条件:
if (john.hasOwnProperty(prop)) {
不允许它记录其原型的属性。
hasOwnProperty
限制 属性 访问迭代中的当前对象。
首先避免使用 proto 因为它在所有浏览器中都不一样。 现在 proto 向原型添加内容,即进行继承。 使用 john.hasOwnProperty(prop) 仅对自己的属性为真,对继承的属性不为真,这就是为什么 getFullName