Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中动态扩展类_Javascript_Class_Inheritance_Prototypal Inheritance - Fatal编程技术网

在javascript中动态扩展类

在javascript中动态扩展类,javascript,class,inheritance,prototypal-inheritance,Javascript,Class,Inheritance,Prototypal Inheritance,如何以动态/编程方式扩展javascript类 更具体地说,假设 class Polygon { constructor(area, sides) { this.area = area; this.sides = sides; } } const Rectangle = extend(Polygon, (length, width) => { super(length * width, 4); this.length = length; this.wi

如何以动态/编程方式扩展javascript类

更具体地说,假设

class Polygon {
  constructor(area, sides) {
    this.area = area;
    this.sides = sides;
  }
}

const Rectangle = extend(Polygon, (length, width) => {
  super(length * width, 4);
  this.length = length;
  this.width = width;
});
我们如何实现类似于
extend
的功能,使其行为与

class Rectangle extends Polygon {
  constructor(length, width) {
    super(length * width, 4);
    this.length = length;
    this.width = width;
  }
}

?这里有三个问题:

(1) super仅在对象方法内部可用,因此无法在arrow函数中访问super。这需要以某种方式替换为常规函数调用

(2) 类只能被构造,不能被调用(不同于充当构造函数的函数)。因此,您不能只
。将
类构造函数调用到“subclass”实例上。您必须创建一个超类实例并将其复制到子类中,最终失去getter/setter

(3) 箭头函数有一个词法
this
,因此您不能在箭头函数中使用
this
访问实例

鉴于这三个问题,可行的替代方案是:

  function extend(superclass, constructor) {
    function Extended(...args) {
      const _super = (...args) => Object.assign(this, new superclass(...args));
      constructor.call(this, _super, ...args);
    }
    Object.setPrototypeOf(Extended, superclass);
    Object.setPrototypeOf(Extended.prototype, superclass.prototype);
    return Extended;
 }

  const Rectangle = extend(Polygon, function(_super, length, width) {
     _super(/*...*/);
     /*...*/
  });

但老实说。。。本机
类有什么问题。。。扩展

这里有三个问题:

(1) super仅在对象方法内部可用,因此无法在arrow函数中访问super。这需要以某种方式替换为常规函数调用

(2) 类只能被构造,不能被调用(不同于充当构造函数的函数)。因此,您不能只
。将
类构造函数调用到“subclass”实例上。您必须创建一个超类实例并将其复制到子类中,最终失去getter/setter

(3) 箭头函数有一个词法
this
,因此您不能在箭头函数中使用
this
访问实例

鉴于这三个问题,可行的替代方案是:

  function extend(superclass, constructor) {
    function Extended(...args) {
      const _super = (...args) => Object.assign(this, new superclass(...args));
      constructor.call(this, _super, ...args);
    }
    Object.setPrototypeOf(Extended, superclass);
    Object.setPrototypeOf(Extended.prototype, superclass.prototype);
    return Extended;
 }

  const Rectangle = extend(Polygon, function(_super, length, width) {
     _super(/*...*/);
     /*...*/
  });

但老实说。。。本机
类有什么问题。。。扩展

经过一些黑客攻击后,我发现这种方法非常有效

function extend(superclass, construct) {
    return class extends superclass {
        constructor(...args) {
            let _super = (...args2) => {
                super(...args2)
                return this;
            };
            construct(_super, ...args);
        }
    };
}

const Rectangle = extend(Polygon, function(_super, length, width) {
         let _this = _super(length * width, 4);
         _this.length = length;
         _this.width = width;
    });

经过一些黑客攻击后,我发现这种方法非常有效

function extend(superclass, construct) {
    return class extends superclass {
        constructor(...args) {
            let _super = (...args2) => {
                super(...args2)
                return this;
            };
            construct(_super, ...args);
        }
    };
}

const Rectangle = extend(Polygon, function(_super, length, width) {
         let _this = _super(length * width, 4);
         _this.length = length;
         _this.width = width;
    });

您正在寻找的被称为原型链接:您正在寻找的被称为原型链接:感谢您提供了信息丰富的直截了当的答案<代码>类。。。extends显然是大多数情况下的解决方案,但我正在寻找一种能够基于一些输入数据以编程方式扩展类的解决方案。具体地说,我正试图通过扩展
HTMLElement
来创建web组件,但是您的解决方案似乎不适合这种情况(
newhtmlelement()
给出了“TypeError:非法构造函数”)。有什么建议可以让它工作吗?因为
HTMLElement
不是一个类,它是一个接口。使用实现它的类。像这样?我仍然看到同样的问题。谢谢你提供了信息丰富的直截了当的答案<代码>类。。。extends显然是大多数情况下的解决方案,但我正在寻找一种能够基于一些输入数据以编程方式扩展类的解决方案。具体地说,我正试图通过扩展
HTMLElement
来创建web组件,但是您的解决方案似乎不适合这种情况(
newhtmlelement()
给出了“TypeError:非法构造函数”)。有什么建议可以让它工作吗?因为
HTMLElement
不是一个类,它是一个接口。使用实现它的类。像这样?我仍然看到同样的问题。奇怪的是,的确如此。虽然我只测试过firefox。这就是我目前正在研究的问题@kag0,我想唯一可以避免传递
\u super
和使用
\u这个
的方法就是使用
eval
:)创建新类,奇怪的是,的确如此。虽然我只测试过firefox。这就是我目前正在研究的问题@kag0,我想避免传递
\u super
和使用
\u这个
的唯一方法是使用
eval
创建新类:)