6

I am trying to learn JavaScript ES6 which is a very cool language and I thought that I should practice a bit but I am not able to make an exercise. So how can I use object literal to copy a class.

For example the class is:

class Point {
  constructor(x, y) {
    this.x = x, this.y = y
  }
  add(other) {
    return new Point(this.x + other.x, this.y + other.y)
  }
}

And I want to do something here using object literal to make the output true.

var fakePoint = YOUR_CODE_HERE
console.log(fakePoint instanceof Point)
AstroCB
  • 12,337
  • 20
  • 57
  • 73

2 Answers2

5

I'll guess that this exercise is looking for a solution that uses __proto__ as an object literal key - as mentioned in the slides:

var fakePoint = {
    __proto__: Point.prototype,
    x: Math.random(),
    y: Math.random()
};
console.log(fakePoint instanceof Point)

However, __proto__ is deprecated (both in object literals and as a Object.prototype getter / setter) and only available in web browsers as a ES6-standardised legacy feature, so I recommend to avoid such code. The proper solution is to use Object.create:

var fakePoint = Object.assign(Object.create(Point.prototype), {
    x: Math.random(),
    y: Math.random()
});
console.log(fakePoint instanceof Point)
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Would you consider this q a dupe of this? https://stackoverflow.com/questions/15472005/setting-prototype-for-object-literal – Andrew Li Dec 19 '17 at 06:47
  • @Li357 Don't think so, none of the answers there uses `__proto__` inside an object literal. Also this question is specifically about ES6. – Bergi Dec 19 '17 at 06:50
  • @vibhor1997a Good for node, they're standard-compliant! See my second paragraph - it's expected to work only in browsers. – Bergi Dec 19 '17 at 06:53
  • @Bergi the second one is logging `true` – vibhor1997a Dec 19 '17 at 06:55
0

Just for fun, here's another approach which probably is not what the exercise author intended but which is arguably an object literal:

var fakePoint = {
  x: Math.random(),
  y: Math.random(),
  fakeConstructor: Object.defineProperty(Point, Symbol.hasInstance, {
    value(o) { return o.fakeConstructor == this; }
  })
};
console.log(fakePoint instanceof Point)

It works by giving Point a custom hasInstance implementation which doesn't check the prototype chain but rather the fakeConstructor property. One could also use "x" in o && "y" in o or something similar. Of course it's horrible to do this side effect as part of an object literal, it would better be written

Object.defineProperty(Point, Symbol.hasInstance, {
  value(o) { return o.fakeConstructor == this; /* this === Point */ }
});
var fakePoint = {
  x: Math.random(),
  y: Math.random(),
  fakeConstructor: Point
};
Bergi
  • 630,263
  • 148
  • 957
  • 1,375