I can create a class that does not inherit from Object.prototype
using the older syntax.
我可以使用旧语法创建一个不从Object.prototype继承的类。
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?
我怎样才能使用ES6课程?
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
2 个解决方案
#1
6
You can use extends null
.
您可以使用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.
请注意,类本身仍将继承自Function.prototype,而不是null。所以你将能够在类上使用函数方法。
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.
但请注意,在使用extends子句时,必须先通过调用super来初始化它,或者不要使用它并在最后返回一个对象。
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.
在这种情况下,您无法使用super初始化它,因为Function.prototype不是构造函数。因此,您必须使用Object.create来创建将成为实例的对象。
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.
new.target将是正在实例化的函数。这可以是Shape本身,也可以是扩展它的其他功能。这对于允许Shape可扩展非常有用。
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
.
如果您不想避免在构造函数中使用它,则另一种方法是扩展其原型为null的函数。缺点是您的类将继承该函数,而不是直接从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
如果您不想重用NullClass,可以将其定义为内联
class Shape extends Object.assign(function(){},{prototype:null}) { /* ... */ }
#2
3
You will have to manually set Shape.prototype
's prototype to null
.
您必须手动将Shape.prototype的原型设置为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);
#1
6
You can use extends null
.
您可以使用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.
请注意,类本身仍将继承自Function.prototype,而不是null。所以你将能够在类上使用函数方法。
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.
但请注意,在使用extends子句时,必须先通过调用super来初始化它,或者不要使用它并在最后返回一个对象。
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.
在这种情况下,您无法使用super初始化它,因为Function.prototype不是构造函数。因此,您必须使用Object.create来创建将成为实例的对象。
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.
new.target将是正在实例化的函数。这可以是Shape本身,也可以是扩展它的其他功能。这对于允许Shape可扩展非常有用。
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
.
如果您不想避免在构造函数中使用它,则另一种方法是扩展其原型为null的函数。缺点是您的类将继承该函数,而不是直接从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
如果您不想重用NullClass,可以将其定义为内联
class Shape extends Object.assign(function(){},{prototype:null}) { /* ... */ }
#2
3
You will have to manually set Shape.prototype
's prototype to null
.
您必须手动将Shape.prototype的原型设置为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);