javascript - 如何使用 ES6 类创建一个不从 Object.prototype 继承的类?

标签 javascript class null prototype ecmascript-6

我可以使用旧语法创建一个不从 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

我如何使用 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

最佳答案

您可以使用extends null

请注意,类本身仍将继承自 Function.prototype,而不是继承自 null。因此,您将能够在类上使用函数方法。

但是请注意,当使用 extends 子句时,您必须在使用 super 之前初始化 this,或者不t 使用 this 并在末尾返回一个对象。

在这种情况下,您不能使用 super 初始化 this,因为 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 将是被实例化的函数。这可以是 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);

如果您不想避免在构造函数中使用this,另一种方法是扩展一个prototypenull 的函数。缺点是您的类将从该函数继承,而不是直接从 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);

如果不想重用NullClass,可以内联定义

class Shape extends Object.assign(function(){},{prototype:null}) { /* ... */ }

关于javascript - 如何使用 ES6 类创建一个不从 Object.prototype 继承的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35932485/

相关文章:

javascript - 尽管它存在于node_modules中,但peerDependency未定义

arrays - PySpark 用数组替换 Null

java - 如何在我自己的类中处理 null 以避免 NullPointerException

function - VB6中如何将空值传递给函数?

c++ - 将指向一个派生类的指针传递给另一个派生类

c++ - 在父类(super class)中调用抽象方法,并在C++中的子类中实现它?

javascript - polymer 3 相对路径

javascript - 查找字符串javascript中出现频率最高的字符

javascript - 从 MySQL 加载数据以在 D3 中用于创建折线图

c++ - C++ 中的类 : Declaring an Instance