I can create a class that does not inherit from Object.prototype using the older syntax.
function Shape(x, y, width, height) {
  this.x = x,
  this.y = y,
  this.width = width,
  this.height = height;
}
Shape.prototype = Object.create(null, {
  constructor: {
    configurable: true,
    writable: true,
    value: Shape
  },
  move: {
    configurable: true,
    writable: true,
    value: function (x, y) {
      this.x += x,
      this.y += y;
    }
  }
});
var rect = new Shape(0, 0, 4, 2);
console.log(Object.getPrototypeOf(rect) === Shape.prototype);
console.log(Object.getPrototypeOf(Object.getPrototypeOf(rect)) !== Object.prototype); //inheritance
How can I do this using ES6 classes?
class Shape {
  constructor(x, y, width, height) {
    this.x = x,
    this.y = y,
    this.width = width,
    this.height = height;
  }
  move(x, y) {
    this.x += x,
    this.y += y;
  }
}
var rect = new Shape(0, 0, 4, 2);
console.log(Object.getPrototypeOf(rect) === Shape.prototype);
console.log(Object.getPrototypeOf(Object.getPrototypeOf(rect)) === Object.prototype); // inheritance
We use the extends keyword to implement the inheritance in ES6. The class to be extended is called a base class or parent class.
The prototype property allows you to add properties and methods to any object (Number, Boolean, String and Date, etc.). Note − Prototype is a global property which is available with almost all the objects. Use the following syntax to create a Boolean prototype.
The function keyword is replaced with the class keyword. There's a special function named 'constructor' where the initialization of the object is done.
You can use extends null.
Note the class itself will still inherit from Function.prototype, not from null. So you will be able to use function methods on the class.
But be aware that, when using an extends clause, you must either initialize this before using it by calling super, or don't use this and return an object at the end.
In this case you can't initialize this using super because Function.prototype is not a constructor. So you will have to use Object.create to create the object that will become the instance.
class Shape extends null {
  constructor(x, y) {
    // Use `that` instead of `this`, and return it at the end
    var that = Object.create(new.target.prototype);
    that.x = x;
    that.y = y;
    return that;
  }
  move(x, y) {
    this.x += x;
    this.y += y;
  }
}
var rect = new Shape(0, 0);
console.log(rect);
console.log(Object.getPrototypeOf(rect) === Shape.prototype);
console.log(Object.getPrototypeOf(Shape.prototype) === null);
console.log(Object.getPrototypeOf(Shape) === Function.prototype);
new.target will be the function that is being instantiated. This can be Shape itself, or another function that extends it. This is useful to allow Shape to be extendable.
class Shape extends null {
  constructor(x, y) {
    // Use `that` instead of `this`, and return it at the end
    var that = Object.create(new.target.prototype);
    that.x = x;
    that.y = y;
    return that;
  }
  move(x, y) {
    this.x += x;
    this.y += y;
  }
}
class BestShape extends Shape {
  constructor(...args) {
    super(...args);
    this.best = true;
  }
}
var rect = new BestShape(0, 0);
console.log(rect);
console.log(Object.getPrototypeOf(rect) === BestShape.prototype);
console.log(Object.getPrototypeOf(BestShape.prototype) === Shape.prototype);
console.log(Object.getPrototypeOf(Shape.prototype) === null);
console.log(Object.getPrototypeOf(BestShape) === Shape);
console.log(Object.getPrototypeOf(Shape) === Function.prototype);
If you don't want to avoid using this in your constructor, an alternative is extending a function whose prototype is null. The downside is that your class will inherit from that function, instead of directly from Function.prototype.
function NullClass() {}
NullClass.prototype = null;
class Shape extends NullClass {
  constructor(x, y) {
    super();
    this.x = x;
    this.y = y;
  }
  move(x, y) {
    this.x += x;
    this.y += y;
  }
}
var rect = new Shape(0, 0);
console.log(rect);
console.log(Object.getPrototypeOf(rect) === Shape.prototype);
console.log(Object.getPrototypeOf(Shape.prototype) === null);
console.log(Object.getPrototypeOf(Shape) === NullClass);
console.log(Object.getPrototypeOf(NullClass) === Function.prototype);
If you don't want to reuse NullClass, you can define it inline
class Shape extends Object.assign(function(){},{prototype:null}) { /* ... */ }
                        You will have to manually set Shape.prototype's prototype to null.
class Shape {
  constructor(x, y, width, height) {
    this.x = x,
    this.y = y,
    this.width = width,
    this.height = height;
  }
    
  move(x, y) {
    this.x += x,
    this.y += y;
  }
}
// This is the key line.
Object.setPrototypeOf(Shape.prototype, null);
const rect = new Shape(0, 0, 4, 2);
console.log(Object.getPrototypeOf(rect) === Shape.prototype);
console.log(Object.getPrototypeOf(Object.getPrototypeOf(rect)) !== Object.prototype);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With