首页 > 解决方案 > 如何在此类中在运行时更改类的原型(使用 ES6 类)

问题描述

我有以下类'X',我想prototype动态添加一些东西,就像这样(这有效):

    class X{
        someUnrelatedFunction(){};	
    }
    
    //adding some stuff at runtime, in real situation, the ['a','b','c'] aren't "known" in advance like here.

    ['a','b','c'].forEach(elem => {
    	X.prototype[elem] = () =>{
      	    console.log('called with : ' + elem);
      };
    })

    //tests:

    x = new X();
    x.c();//works, outputs 'called with : c';

class声明本身。我想这样做,使事情更具可读性,即我希望“原型”初始化属于类本身。

现在我正在“构造函数”中执行此操作,如下所示:

class X{
	constructor(){
  	//we don't want to do that again:
  	if(typeof X.prototype.inited === 'undefined'){
    	X.prototype.inited = true;
    	console.log('-constructor: initing prototype');
      ['a','b','c'].forEach(elem => {
        X.prototype[elem] = () =>{
          console.log('called with : ' + elem);
        };
      })      
  	}else{
    	console.log('-constructor: no need to re-init prototype');
    }	
  }
}


x1 = new X();
x1.a();

x2 = new X();
x2.b();

小提琴:https ://jsfiddle.net/nypL29f3/4/

但这对我来说似乎很棘手,而且在课堂上我实际上是在“外部”引用它,即我使用的是“X”。如果我更改了类名,我还需要更改那部分代码。

所以问题是 - 如何以更易读和正确的方式做到这一点?

FWIW,“真实”的情况是我通过创建像这样的无用脚本来玩 ES6:

https://jsfiddle.net/kpion/mqyrewnx/9/

在这里,我的疑虑是关于第 78 行 //这是我的问题 - 似乎我需要在 YaLog 类之外进行。

编辑:顺便说一句-如果您带着类似的问题来到这里-以下所有答案都以某种方式回答了该问题,并且都值得一读。谢谢大家!:)

标签: javascriptecmascript-6

解决方案


我希望“原型”初始化属于类本身。

这是不可能的。类体只能包含方法定义,不能包含任意代码。

如果方法的数量是已知的并且只有它们的名称是动态的,您可以使用计算的属性名称,但在您的示例中似乎并非如此。

由于您正在寻找一种更具可读性的方式,只需将类和静态值的所有分配或动态创建的方法放在单独的模块中即可。(这可能是一个 ES6 模块、一个 IIFE 模块或一个用于视觉分离的简单块作用域)。

现在我正在做这个constructor

不。这是低效的、容易出错的并且非常难以理解。


推荐阅读