0

let shape = {
  type: 10,
  getTyp() {
    return "triangle";
  }
};

function Triangle() {}
Object.setPrototypeOf(Triangle, shape);
let t = new Triangle();
console.dir(t.type); //undefined

Why doesn't the prototype of Triangle change? t.type === undefined but not 10 ;

FZs
  • 16,581
  • 13
  • 41
  • 50
  • why not just `Object.create(shape)` ? There's a warning on very first line on [`setPrototypeOf MDN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf) about this why should avoid this – Code Maniac Sep 23 '19 at 16:32
  • 1
    By the way, there's nothing in this question that has anything to do with ECMAScript 2019 specification. – Patrick Roberts Sep 23 '19 at 16:34
  • 1
    `[[Prototype]]` vs `prototype` is perhaps the most confusing thing in javascript. – georg Sep 23 '19 at 16:39

4 Answers4

0

You've confused Constructor.prototype with instance's internal [[Prototype]], what Object.setPrototypeOf() sets.

You should use the former in this case:

  let shape = {
  type: 10,
  getTyp() {
    return "triangle";
  }
};

function Triangle() {}
Triangle.prototype=shape;
let t = new Triangle();
console.dir(t.type); //10

The above works, but, to ensure class constructor point to the correct function, don't overwrite the Constructor.prototype. Instead, assign properties to it:

  let shape = {
  type: 10,
  getTyp() {
    return "triangle";
  }
};

function Triangle() {}
Object.assign(Triangle.prototype,shape);
let t = new Triangle();
console.dir(t.type); //10
Edgar
  • 6,022
  • 8
  • 33
  • 66
FZs
  • 16,581
  • 13
  • 41
  • 50
  • 1
    `don't ever overwrite the Constructor.prototype!` ... why? – Jonas Wilms Sep 23 '19 at 16:35
  • @JonasWilms Another urban legend busted about `instanceof`: I've heard that overwriting `Constructor.prototype` will cause `instaceof` malfunction... But, now I found the only problem with it: https://stackoverflow.com/a/12260750/8376184 – FZs Sep 23 '19 at 16:45
0

Cause instances of Triangle inherit from the Triangle.prototype. You want to change that:

 Object.setPrototypeOf(Triangle.prototype,/*...*/);

If you set the prototype of Triangle, you can access the property directly on Triangle:

  Triangle.shape

Thats basically how static properties get inherited

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • 1
    Might be worth pointing out that `Object.setPrototypeOf(Triangle.prototype, shape)` adds an additional level to the prototype chain compared to `Triangle.prototype = shape` – Patrick Roberts Sep 23 '19 at 16:36
0

Instead of

Object.setPrototypeOf(Triangle, shape)

all you need to do is

Triangle.prototype = shape

Object.getPrototypeOf(Triangle) refers to Triangle[[Prototype]] (or the non-standard Triangle.__proto__ property), not Triangle.prototype as you seem to be anticipating.

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
-1

According to the documentation, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf, the first argument of this function should be an object. You passed it a class.

This isn't what you want, but it's an example of how to properly use that function:

let shape = {
  type: 10,
  getTyp() {
    return "triangle";
  }
};

const Triangle = {};
Object.setPrototypeOf(Triangle, shape);
let t = Triangle;
console.dir(t.type);

[edit]

Here's another concept:

let shape = {
  type: 10,
  getTyp() {
    return "triangle";
  }
};

function Triangle() {
  Object.setPrototypeOf(this, shape);
}
let t = new Triangle();
console.dir(t.type); //undefined
TKoL
  • 13,158
  • 3
  • 39
  • 73