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