本文经原作者FernandoDoglio授权翻译。并不是说JS中的类有什么问题,但如果你已经使用该语言一段时间,尤其是ES5,那么你可能会意识到从原型继承到当前类模型的演变。原型链有什么问题?在我看来,这个问题的答案是:不。但社区花了数年时间才将类的概念强加到不同的结构和库中,因此ECMA技术委员会决定无论如何都要添加它。你问这有什么问题?这就是他们真正所做的,在我们已有的原型继承之上进行一些组合,并决定将其称为类,这反过来又让开发人员认为他们正在处理一种面向对象的语言,而实际上他们不是。类只不过是语法糖jS没有完整的OOP支持,它从来没有,那是因为它从来不需要它。从表面上看,当前版本的类显示了OOP范例,因为:我们可以创建基本的类定义,以非常经典的语法将状态和行为组合在一起。我们可以从一个类继承到另一个类。我们可以定义属性和方法在公有和私有之间的可见性(尽管私有字段仍然是一个实验特性)。我们可以为属性定义getter和setter。我们可以实例化类。那么为什么我说类是语法糖呢?因为虽然从表面上看,它们看起来非常面向对象,但是如果我们试图做一些超出它们可能的事情,比如定义一个扩展两个类的类(目前不可能的事情),我们需要使用下面的代码//辅助函数函数(derivedCtor.prototype,name,descriptor);});});}classA{methodA(){console.log('A')}}classB{methodB(){console.log('B')}}classC{}//使用mixin我们需要这样做,因为在JS中我们不能写:classA{methodA(){console.log("A")}}classB{methodB(){console.log("B")}}classCextendsA,B{}在上面的例子中,关键部分应该是applyMixins函数。以防万一,您不完全理解它试图做什么,但您可以清楚地看到它正在访问所有类的原型属性以复制和重新分配方法和属性。这就是我们需要看清真相的地方:类只不过是已证实的原型继承模型之上的语法糖。这是否意味着我们应该停止使用类?当然不是,理解它很重要,如果我们想做一些超出类范围的事情,那么我们就必须处理原型。JS的OOP模型缺少什么?如果我们当前的OOP模型如此薄,只是一个原型继承的抽象层,我们到底缺少什么?是什么让JS真正面向对象?看这个问题的好方法就是看看TypeScript是干什么的。该语言背后的团队通过创建可以翻译成JS的东西,无疑将JS推向了极限。这反过来又限制了他们的能力。一些当前在JS中缺失的OOP结构具有内在类型检查并且在动态类型语言中没有实际意义,这可能是它们尚未添加的原因。接口接口帮助定义一个类应该符合的API。接口的主要好处之一是我们可以定义实现相同接口的任何类的变量,然后安全地调用它的任何方法。interfaceAnimal{speak()}classDogimplementsAnimal{speak(){console.log("Woof!")}}classCatimplementsAnimal{speak(){console.log("Meau!")}}classHumanimplementsAnimal{speak(){console.log("Heydude,what'sup?")}}//如果我们在JS中有接口,我们可以安全地做:letobjects=[newDog(),newCat(),newHuman()]objects.forEach(o=>o.speak())当然,我们可以通过定义speak方法并覆盖它的类来实现同样的事情,但是界面更加清晰和优雅。抽象类每当我尝试用我的代码进行完整的OOP时,我肯定会想念JS中的抽象类。抽象类是定义和实现方法但从不实例化的类。这是一种对可以扩展但从不直接使用的常见行为进行分组的方法。这是一个很好的资源,绝对可以在当前的JS环境中实现而无需太多努力。静态多态性静态多态性允许我们在同一个类中多次定义相同的方法,但具有不同的签名。换句话说,重复名称,但确保它接收不同的参数。现在我们有了JS的剩余参数,这允许我们有任意数量,但是,这也意味着我们必须在方法中添加额外的代码来处理这种动态性。相反,我们可以更清楚地区分方法签名,因此我们可以将相同行为的不同含义直接封装到不同的方法中。左边的版本不是有效的JS,但它提供了更清晰的代码,因此更易于阅读和理解。右边的版本是完全有效的,它更难阅读并且需要一些ES6语法。多态性通常通过查看方法中接收的参数类型来实现。但是,我们知道由于JS的工作方式,这是不可能的。我们已经对受保护的属性和方法具有公共可见性,并且我们很快获得了对方法和属性的私有可见性(通过#前缀)。我认为下一步应该是添加受保护的可见性,但是,目前还没有,如果您想拥有适当的OOP体验,我认为这三者都是必要的。受保护的属性和方法只能从类内部或其子类之一访问(与私有可见性相反,私有可见性仅限于父类)。今天和大家分享的就这些了,我是小智,我们下期再见。作者:FernandoDoglio译者:FrontendXiaozhi来源:meidum原文:https://blog.bitsrc.io/whats-wrong-with-javascript-s-classes-3378c73205af,可通过以下二维码关注。转载本文请联系大千世界公众号。
