匿名类实例----这是个坏主意吗?

Posted

技术标签:

【中文标题】匿名类实例----这是个坏主意吗?【英文标题】:Anonymous class instance ---- is it a bad idea? 【发布时间】:2016-12-08 22:24:13 【问题描述】:

在 ES6 中我们可以做匿名类:

var entity = class 

但我们也可以实例化它:

var entity = new class 
    constructor(name)  this.name = name; 
    getName()  return this.name; 
('Foo');
console.log(entity.getName()); // Foo

它背后做了什么,它会带来什么好处,它还会带来什么警告?

【问题讨论】:

为什么不直接使用对象字面量?还是实际的构造函数? 个人口味;我喜欢 C++ 和 Java 风格的对象声明。 我不认为这和普通的原型类创建有什么不同。这只是语法差异。 quora.com/… 看起来这个博客条目足够体面,可以与我的问题相关:jasonwyatt.co/post/866536821/… ES5 也有匿名构造函数:entity = new function(name) this.name = name ("Foo")class 只是构造函数和一些附加功能的语法糖。因此,当有匿名构造函数时,也会有匿名类。 【参考方案1】:

匿名类实例——这是个坏主意吗?

是的,非常糟糕。只需as bad as new function() … was in ES5。

这种写作风格导致每次计算表达式时都会创建一个新的构造函数和原型对象。如果您使用这种方法创建多个对象,它们将无法获得类/原型的任何好处。

如果您打算使用此模式创建单例对象,那么您也失败了。构造函数仍在创建中,甚至可以访问 - 使用 new entity.constructor 可以轻松创建第二个实例,从而破坏了整个目的。

所以永远不要使用它。一个简单的对象字面量更容易编写、读取和实例化:

var entity = 
    name: 'Foo',
    getName()  return this.name; 
;
console.log(entity.name); // Foo

不要被new class 模式很常见的其他语言所迷惑,它的工作方式与 javascript 中的非常不同。

【讨论】:

读者应该注意引用“这种写作风格导致每次计算表达式时都会创建一个新的构造函数和原型对象。如果你用这种方法创建多个对象,他们将一无所获类/原型的好处。” -- 除非我误解了,否则这是对为每个对象创建匿名类的有效反对意见,但不一定是对使用匿名类创建多个对象的反对意见,在这种情况下,它们仍将受益于原型继承。 (其他反对意见可能存在也可能不存在。) @ninjagecko 是的,反对将class 用于一般的“单身人士”。它甚至不需要匿名。 如果你将它用于单身人士,你还没有“失败”。您可以通过简单地克隆来创建 any 对象的第二个实例。 JavaScript 是一种动态语言,具有自省、eval 和可以在运行时修改的标准库。如果您希望从恶意或愚蠢的同事那里锁定您的代码,那么您肯定选择了错误的编程语言! @alextgordon 使用闭包的对象不容易被克隆,如果单例的设置逻辑不包含在(构造函数)方法中,通常不能运行两次。 您没有提供任何反对使用匿名类的明确论据。类/原型的好处?当使用匿名类时,它们到底是什么?至于“每次评估时创建一个类”,这完全取决于在程序过程中发生的频率(多少次)。在某些情况下,不利因素可能可以忽略不计。但作为一般规则,是的,我建议坚持普通课程。除非你有理由不这样做。【参考方案2】:

如果您确切地知道自己在做什么,您可能需要匿名类,您正在一个经过深思熟虑的元编程系统中创建类的层次结构(即您想要复制的东西),并且没有其他优雅的解决方案扩展,例如


    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 等等……还是不想要?你是否坚持使用已经存在的类,或者你可以使用 Objects 和 asserts 编写所有东西吗?是吗?真的需要匿名吗?这些问题可能会帮助您做出决定。)。

【讨论】:

以上是关于匿名类实例----这是个坏主意吗?的主要内容,如果未能解决你的问题,请参考以下文章

为什么匿名内部类可以实例化并实现抽象方法?lambda表达式是简化了匿名内部类的实现过程吗?

匿名内部类简单实例

使用 SPOON 创建匿名类的实例

请问JAVA中匿名内部类有啥用,举个例子,谢谢

Java匿名内部类和Lambda表达式

匿名内部类