0

I was reading on "professional javascript for web developers" when the author said :

The constructor property was originally intended for use in identifying the object type. However, the instanceof operator is considered to be a safer way of determining type enter image description here

can you explain what is the concern behind not using constructor over instanceof to determine object type?

traditional example with no differences maybe like:

car instanceof Car  // true
car.constructor === Car // true

Thanks...

Ayman Morsy
  • 1,279
  • 1
  • 10
  • 28
  • might have to do with subclasses. if B is a subclass of A, `constructor` will return false but `instanceof` will return true – TKoL Sep 09 '20 at 09:20
  • `car.constructor = "I'm not a constructor"` – VLAZ Sep 09 '20 at 09:23
  • @VLAZ if you do that, will it still run the constructor defined in the class when you call `new Class`? – TKoL Sep 09 '20 at 09:24
  • answer is yes, it will – TKoL Sep 09 '20 at 09:25
  • @TKoL yes. Because we add a new property to the instance itself, however, the constructor that comes from the prototype would stay but would be "shadowed". You can get it by doing `Object.getPrototypeOf(car).constructor`. However, OP is asking for `car.constructor === Car` and *that* would fail. EDIT: you can also overwrite that constructor, as well. – VLAZ Sep 09 '20 at 09:26

1 Answers1

2

class A {

}

class B extends A {

}

var x = new B();

console.log('instanceof A', x instanceof A);
console.log('instanceof B', x instanceof B);
console.log('constructor = A', x.constructor === A);
console.log('constructor = B', x.constructor === B);

Subclassing makes a difference

TKoL
  • 13,158
  • 3
  • 39
  • 73
  • thanks , The author wasn't know about es6 at that time of publishing the book . could you adding es5 version to make it easier for me – Ayman Morsy Sep 09 '20 at 09:35
  • I'm not sure what the es5 syntax is that's equivalent to `extends` – TKoL Sep 09 '20 at 09:37
  • 1
    @AymanMorsy [see here for an example](https://stackoverflow.com/a/56942974/). In ES5 "extending" is done as a more direct prototype manipulation. You'd create class A (or constructor function A) then create class B (or constructor function B). Afterwards set it up so B uses A's prototype but change the constructor of that prototype back to B, so you don't lose it. See also [What's the actual purpose of prototype.constructor](https://stackoverflow.com/q/59715125) and the duplicate links from there. – VLAZ Sep 09 '20 at 10:12
  • @VLAZ does that have the same relationship as above with `instanceof` vs `instance.constructor`? – TKoL Sep 09 '20 at 13:42
  • looks like it does actually. – TKoL Sep 09 '20 at 13:46
  • 1
    @TKoL yes, `B extends A` will broadly do the same thing as the ES5 version. Overall, the class syntax is just syntactic sugar over the same prototype inheritance and mechanics which ES5 has, so both would work the same way. The major difference is that ES6 has the concept of constructable and non-constructable functions, so an ES6 class constructor cannot be called *without* `new` and ES6 class methods cannot be called *with* `new`. ES5 doesn't have away to enforce this, so you can call `MyConstructor()` or `new myInstance.myMethod()`. Other than that, the ES6 class syntax should work the same – VLAZ Sep 09 '20 at 13:58
  • Thanks guys for your times , I can add another example got inspired from this answer may help if anyone come here later : https://i.imgur.com/S6jQJGH.png – Ayman Morsy Sep 13 '20 at 12:39