javascript - 如何检查属性是否仅属于 Javascript 中的子类或子类?

标签 javascript node.js ecmascript-6

我正在尝试获取仅存在于子类(子类)中而不存在于 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/

相关文章:

node.js - 如果我导入没有 `ERR_MODULE_NOT_FOUND` 扩展名的文件,ExpressJs 将返回错误 `js`

javascript - 如何区分箭头函数、类和普通函数?

javascript - 选中复选框后如何显示textarea和select标签?

javascript - 正确使用 Promises 和 Await/Async

javascript - 向信息窗口添加更多数据

javascript - 自适应卡在提交时清除输入

javascript - Node.js 中低于全局范围的范围

Javascript 奇怪的生成器 yield 子函数行为

javascript - 即使在不同的 HTML 页面或刷新页面时,如何继续以 HTML 格式播放相同的音乐

javascript - 将 JSON.parse() 返回类型转换为对象数组