在 ES6 中,我们可以使用匿名类:
var entity = class {
}
但是我们也可以立即实例化它:
var entity = new class {
constructor(name) { this.name = name; }
getName() { return this.name; }
}('Foo');
console.log(entity.getName()); // Foo
背后做了什么,它会带来什么好处,也会带来什么注意事项?
在 ES6 中,我们可以使用匿名类:
var entity = class {
}
但是我们也可以立即实例化它:
var entity = new class {
constructor(name) { this.name = name; }
getName() { return this.name; }
}('Foo');
console.log(entity.getName()); // Foo
背后做了什么,它会带来什么好处,也会带来什么注意事项?
立即实例化匿名类——这是一个坏主意吗?
是的,非常糟糕。就像在ES5中使用new function() { ... }
一样糟糕。
这种写法会导致每次评估表达式时都创建一个新的构造函数和原型对象。如果您使用此方法创建多个对象,则它们将不会获得类/原型的任何好处。
如果您打算使用此模式创建单例对象,则也失败了。构造函数仍然被创建,并且甚至可以访问-使用new entity.constructor
可以轻松创建第二个实例,从而破坏整个目的。
因此,永远不要使用它。一个简单的对象字面量更容易编写、阅读和实例化:
var entity = {
name: 'Foo',
getName() { return this.name; }
};
console.log(entity.name); // Foo
class
来表示“单例模式”。即使不是匿名类也是如此。 - Bergi如果您清楚自己在做什么,正在创建类层次结构(即想要复制的东西)的元编程系统,并且没有其他优雅的扩展解决方案,则可能需要使用匿名类。
{
myImplementation: class extends MyBaseClass {
someMethod(x) {
super().someMethod(x);
insert extended behavior
}
}
}
当然,您可以使用一些滥用魔法函数来实现上述功能,这些函数使用Object.assign
:
{
myImplementation: extendMagic(mySuper => ({
someMethod(x) {
mySuper.someMethod(x);
insert extended behavior
}
}))
}
或者找到更好的方法来完成您正在做的事情。但是人为制造的用例偶尔(虽然很少)存在。
这些用例从未很好,但当您需要使用难以使用原型继承编写的类功能时,它们最具有说服力(当然,由于类是原型继承的包装器,因此您的用例归结为想要语法糖加上ES6+类功能...您是否需要构造函数、super、extends、staticmethod等?您是否被困在已经存在的类中,还是可以使用对象和断言编写所有内容?并且它真的需要是匿名的吗?这些问题可能会帮助您做出决定。)
entity = new function(name) { this.name = name }("Foo")
。class
只是语法糖,用于表示一个构造函数和一些额外的内容。因此,当存在匿名构造函数时,也会存在匿名类。 - user6445533