我正在尝试获取仅存在于子类(子类)中而不存在于 Javascript 父类中的属性(不包括函数)。我正在使用 .hasOwnProperty()
但它也为父类的属性提供了 true
。我在 Node 中运行它。
代码:
class Model{
constructor(){
this.location = 'Gotham'
}
}
class Superhero extends Model{
}
const superhero = new Superhero()
superhero.alias = 'Batman'
superhero.realName = 'Bruce Wayne'
for (const property in superhero){
if (superhero.hasOwnProperty(property) && (typeof superhero[property] !== 'function')){
console.log(`${property} = ${superhero[property]}`)
}
}
输出:
location = Gotham
alias = Batman
realName = Bruce Wayne
我想要得到的输出:
alias = Batman
realName = Bruce Wayne
请帮忙!!
最佳答案
您的所有属性都不在“父”或“子”类中,它们都在通过 new Superhero
创建的实例(对象)中。查看实例,无法判断 location
是由 Model
构造函数添加到实例中的,而另外两个是由 添加到实例中的 super 英雄
构造函数。该信息不是 JavaScript 中对象模型的一部分。
从你开始循环的地方开始,这是你内存中的内容(省略了一些细节):
+−−−−−−−−−−−−+ Model−−−−−−>| (function) | +−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | prototype |−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−>| (object) | +−−−−−−−−−−−−+ / +−−−−−−−−−−−−−−−+ | | [[Prototype]] |−−−−>Object.prototype | +−−−−−−−−−−−−−−−+ | | +−−−−−−−−−−−−+ | Superhero−−>| (function) | | +−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | | prototype |−−−−+−>| (object) | | +−−−−−−−−−−−−+ / +−−−−−−−−−−−−−−−+ | | | [[Prototype]] |−−+ | +−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−+ \ +−−−−−−−−−−−−−−−−−−−−−−−−−+ | superhero−−>| (object) | | +−−−−−−−−−−−−−−−−−−−−−−−−−+ | | [[Prototype]] |−−−+ | location: "Gotham" | | alias: "Batman" | | realName: "Bruce Wayne" | +−−−−−−−−−−−−−−−−−−−−−−−−−+
As you can see, all the properties are on the instance itself.
If instance
were on a prototype of the instance, you'd be able to differentiate them, but not with what you have where they're all properties on the instance itself.
You can move location
to a prototype (specifically, the prototype of the prototype of the instance) by making it an accessor property:
class Model {
constructor() {
// This makes _location non-enumerable and non-configurable
Object.defineProperty(this, "_location", {
value: "Gotham",
writable: true
});
}
get location() {
return this._location;
}
set location(value) {
this._location = value;
}
}
// Make our "location" accessor property enumerable (if you want it to be).
// By default, accessors defined in class notation are non-enumerable.
{
const desc = Object.getOwnPropertyDescriptor(Model.prototype, "location");
desc.enumerable = true;
Object.defineProperty(Model.prototype, "location", desc);
}
class Superhero extends Model {
}
const superhero = new Superhero();
superhero.alias = 'Batman';
superhero.realName = 'Bruce Wayne';
for (const property in superhero){
if (superhero.hasOwnProperty(property) && typeof superhero[property] !== 'function') {
console.log(`${property} = ${superhero[property]}`)
}
}
在那个例子中,因为我们必须将 location
的值存储在某个地方,所以我创建了一个 _location
属性来存储它。不过,它仍然在实例上,并且可以在不通过访问器的情况下进行设置。 (它没有出现在 for-in
循环中,因为我让它不可枚举。)如果我们真的想保护它,我们必须将它与实例分开存储,可能通过使用由实例本身键入的 WeakMap
。但通常没有必要走那么远。
关于javascript - 如何检查属性是否仅属于 Javascript 中的子类或子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50943016/