Guerric P
Guerric P

Reputation: 31805

How instanceof works?

Given this code:

/**
 * Transform base class
 */
function Transform() {
    this.type = "2d";
}

Transform.prototype.toString = function() {
    return "Transform";
}

/**
 * Translation class.
 */
function Translation(x, y) {
    // Parent constructor
    Transform.call(this);

    // Public properties
    this.x = x;
    this.y = y;
}

// Inheritance
Translation.prototype = Object.create(Transform.prototype);

translation = new Translation(10, 15);

console.log(translation instanceof Transform); // true
console.log(translation instanceof Translation); // true

console.log(translation.__proto__); // Transform
console.log(translation.constructor); // Transform

Why translation.constructor is Transform and not Translation? Also, which property allows instanceof to know that translation is an instance of Translation (if it's not __proto__ nor constructor)?

Upvotes: 0

Views: 112

Answers (1)

adiga
adiga

Reputation: 35202

Why translation.constructor is Transform and not Translation?

Because you have missed a step while creating a subclass Translation. Every function gets a default prototype property and this has a constructor property equal to the function itself.

function Translation() {
}

const translation = new Translation();

console.log(Translation.prototype.constructor === Translation)
console.log(translation.constructor === Translation)

console.log(translation.__proto__ === Translation.prototype)
console.log(Object.getPrototypeOf(translation) === Translation.prototype)

So, why doesn't translation.constructor return Translation in your case? Because, to inherit from Transform, the default prototype is overwritten.

Translation.prototype = Object.create(Transform.prototype);

^ When you did that, the default prototype object which had the constructor got overwritten with a new object. If you check the documentation for Classical inheritance, you have missed a step in creating this inheritance. You need to set the constructor property to the original function. This will help identify the constructor function that created an object

Translation.prototype.constructor = Translation

If you don't add this, a call to translation.constructor will be as follows:

  • It will look for a constructor property directly on the object. It doesn't exist.
  • Then it will look inside Translation.prototype. This object was overwritten by the Object.create(Transform.prototype) line and the object doesn't have any own properties.
  • Translation.prototype falls back to Transform.prototype. There is a constructor property here an it is the function Transform. This is why you get Transform

And as to why instanceof works is explained in this answer from the duplicate.

Upvotes: 2

Related Questions