Is there a counterpart to Object.prototype.hasOwnProperty?

Viewed 39

Given is the following exemplary class structure:

class matter {
  constructor(atomicNumber) {
    this.atomicNumber = atomicNumber;
  }
}

class stone extends matter {
  constructor(atomicNumber, mohsHardness) {
    super(atomicNumber);
    this.mohsHardness = mohsHardness;
  }

  showProperties() {
    console.log(Object.getOwnPropertyNames(this));
  }
}

class gem extends stone {
  constructor(atomicNumber, mohsHardness, carat) {
    super(atomicNumber, mohsHardness);
    this.carat = carat;
  }
}

let chunk = new gem(6, 10, 1);
chunk.showProperties();

The output of function Object.getOwnPropertyNames is, as expected,

['atomicNumber', 'mohsHardness', 'carat']

How do I get only the properties of the "parent" classes, as there would be

['atomicNumber', 'mohsHardness']

If I replace the function like this:

showProperties() {
    const parentClass = Object.getPrototypeOf(Object.getPrototypeOf(this));
    console.log(Object.getOwnPropertyNames(parentClass));
}

I get the result

['constructor', 'showProperties']

That leaves me at a loss. Maybe there is a counterpart to Object.prototype.hasOwnProperty?

1 Answers

The problem is that when a child instance is created, the this referred in the matter and stone constructors is exactly the same object as the this referenced in the child constructor (the gem). After the child constructor changes the instance, there's no way to differentiate a property added by the child constructor from a property added by a super constructor.

The only way to do something like this would be to check the object after the super call is done, before the child constructor mutates the object:

class matter {
    constructor(atomicNumber) {
        this.atomicNumber = atomicNumber;
    }
}

class stone extends matter {
    constructor(atomicNumber, mohsHardness) {
        super(atomicNumber);
        this.mohsHardness = mohsHardness;
    }

    showProperties() {
        console.log(this.parentProperties);
    }
}

class gem extends stone {
    constructor(atomicNumber, mohsHardness, carat) {
        super(atomicNumber, mohsHardness);
        this.parentProperties = Object.getOwnPropertyNames(this);
        this.carat = carat;
    }
}

let chunk = new gem(6, 10, 1);
chunk.showProperties();

Related