简体   繁体   中英

How can I use an object literal to make an instance of a class without useing the constructor in JavaScript ES6?

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)

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)

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
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM