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

Mic*_*iot 6 javascript null prototype class 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
Run Code Online (Sandbox Code Playgroud)

我怎样才能使用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
Run Code Online (Sandbox Code Playgroud)

Ori*_*iol 6

你可以用extends null.

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

但请注意,使用extends子句时,必须this先通过调用初始化super,或者不要this在最后使用和返回对象.

在这种情况下,您无法初始化this使用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);
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

如果你不希望避免使用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);
Run Code Online (Sandbox Code Playgroud)

如果您不想重复使用NullClass,可以内联定义它

class Shape extends Object.assign(function(){},{prototype:null}) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)