JavaScript类问题详解

并不是说 JS 的类有问题,但是如果你使用该语言已有一段时间,特别是使用过ES5,那么你可能就知道了从原型继承到当前类模型的演变。

原型链会有什么问题?

以我的拙见,这个问题的答案是:没有。但是社区花了很多年的时间才将类的概念强加到不同的结构和库中,因此ECMA技术委员会决定无论如何都要添加它。

你会问,这有什么问题吗?这就是他们真正做的,在我们已经拥有的原型继承之上添加了一些构成,并决定将其称为类,这反过来又让开发人员认为他们正在处理一种面向对象的语言,而实际上它们并不是。

类只不过是语法糖

jS 没有完全的 OOP 支持,它从来没有,这是因为它从来都不需要它。

表面上,当前版本的类显示OOP范例,因为:

我们可以创建基本的类定义,用非常经典的语法将状态和行为分组在一起。

我们可以从一个类继承到另一个类。

我们可以在公有和私有之间定义属性和方法的可见性(尽管私有字段仍然是一个实验性的特性)。

我们可以为属性定义getter和setter。

我们可以实例化类。

那么为什么我说类是语法糖呢?因为尽管在表面上,它们看起来是非常面向对象的,但是如果我们试图做一些超出它们可能的事情,比如定义一个类扩展两个类(目前不可能的事情),我们需要使用下面的代码

// 辅助函数
function applyMixins(derivedCtor, baseCtors) {
   baseCtors.forEach(baseCtor => {
       Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
           let descriptor = Object.getOwnPropertyDescriptor(baseCtor.prototype, name)
           Object.defineProperty(derivedCtor.prototype, name, descriptor);
       });
   });
}

class A {
 methodA () {
   console.log('A')
 }
}

class B {
 methodB () {
   console.log('B')
 }
}

class C {

}
// 使用 mixins

我们需要这样做,因为在JS中我们无法编写:

class A {

   methodA(){
       console.log("A")
   }
}

class B {

   methodB(){
       console.log("B")
   }
}

class C extends A, B {

}

在上面的示例中,关键部分应该是applyMixins函数。如果,你没有完全理解它试图做什么,但可以清楚地看到它正在访问所有类的原型属性来复制和重新分配方法和属性。这就是我们需要看到真相的地方:类只不过是在经过验证的原型继承模型之上的语法糖。

这是否意味着我们应该停止使用类?当然不是,重要的是要理解它,而且如果我们想做些突破类的限制,那么我们就必须用原型来处理。

JS 的OOP 模型缺失了什么呢?

如果我们当前的OOP模型是如此之薄,仅是原型继承的抽象层,那么我们到底缺少什么呢?是什么让JS真正成为OOP?

看这个问题的一个好方法就是看看TypeScript在做什么。该语言背后的团队通过创建一些可以翻译成JS的东西,无疑将 JS 推向了极限。这反过来也限制了它们的能力。

目前 JS 中缺失的一些OOP构造具有内在的类型检查功能,在动态类型语言中没有真正的意义,这可能是它们还没有被添加的原因。

接口

接口可帮助定义类应遵循的API。接口的主要好处之一是,我们可以定义实现相同接口的任何类的变量,然后安全地调用其任何方法。

interface Animal {
 speak()
}

class Dog implements Animal{
 speak() {
   console.log("Woof!")
 }
}

class Cat implements Animal{
 speak() {
   console.log("Meau!")
 }
}

class Human implements Animal{
 speak() {
   console.log("Hey dude, what's up?")
 }
}

//如果我们在JS中有接口,我们可以放心地做: let objects = [new Dog(), new Cat(), new Human()] objects.forEach(o => o.speak()) 当然,我们可以通过定义speak方法并覆盖它的类来实现同样的目的,但接口更加清晰和优雅。

抽象类

每当我尝试对我的代码进行完整的OOP操作时,我肯定会错过JS中的抽象类。抽象类是定义和实现方法的类,但永远不会实例化。这是一种可以扩展但从未直接使用的常见行为的分组方式。这是一个很好的资源,并且绝对可以在当前JS领域内实现而不会花费太多精力。

静态多态

静态多态性使我们可以在相同的类中多次定义相同的方法,但是具有不同的签名。换句话说,重复该名称,但要确保其接收不同的参数。现在我们有了JS的rest参数,这使我们可以拥有一个任意数字,但是,这也意味着我们必须在方法中添加额外的代码来处理这种动态性。相反,我们可以更清楚地区分方法签名,则可以将相同行为的不同含义直接封装到不同方法中。

左边的版本不是有效的JS,但它提供了一个更干净的代码,因此,阅读和理解起来比较容易。右边的版本是完全有效的,它阅读起来相对困难些,还要懂得一些 ES6 的语法。

多态性通常是通过查看方法中接收到的参数的类型来实现的。但是,由于JS的工作原理,我们知道这是不可能的。

受保护的属性和方法

我们已经有了公开的可见性,而且我们很快就得到了方法和属性的私有可见性(通过#前缀)。我认为下一步应该是添加受保护的可见性,然而,现在还没有,我认为如果你想要有一个合适的OOP体验,这三个都是必要的。受保护的属性和方法只能从类内部或它的一个子类中访问(与私有可见性相反,私有可见性将访问限制为只能访问父类)。

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/222910.html<

(0)
管理的头像管理
上一篇2025-04-15 17:27
下一篇 2025-04-15 17:29

相关推荐

  • GEO友好的服务器标准有哪些,如何判断?

    SEO友好的服务器,核心标准是速度、稳定性、IP纯净度、安全合规以及服务商资质,缺一不可, 选择服务器不能只看配置,更要关注机房基础设施、网络质量、IP信誉以及服务商是否持牌经营,符合这些条件的服务器,才能让百度爬虫顺利抓取、用户获得良好体验,从而稳定提升排名,速度:服务器响应时间与硬件配置百度最新的核心算法中……

    2026-07-26
    0
  • 机房T3等级是什么意思?,T3机房等级标准有哪些?

    机房T3等级,代表数据中心具备并行维护能力和N+1冗余架构,可用性达到99.982%级别,是当前企业托管业务的主流选择,什么是机房T3等级?核心定义与行业标准机房T3等级源自Uptime Institute的数据中心分级标准,也对应TIA-942的Rating 3等级,这个等级的核心特征就是可并行维护——在任意……

    2026-07-26
    0
  • 服务器SLA服务协议是什么有什么用,有哪些注意事项?

    服务器SLA服务协议是服务商与用户之间关于服务可用性、性能等方面的正式承诺,它直接决定了业务稳定性和运维成本,什么是服务器SLA服务协议服务器SLA(Service Level Agreement)是服务等级协议的缩写,在IDC和云服务领域,它是一份具有法律效力的合同附件,明确服务商必须提供的服务水平基准,这份……

    2026-07-26
    0
  • 站群服务器泛站和泛目录有什么区别?,怎么选

    泛站基于多个独立域名构建独立站点,泛目录则在同一域名下通过目录结构构建内容,这直接影响SEO权重分配和资源管理,什么是泛站和泛目录泛站模式泛站模式使用多个独立域名,每个域名部署独立网站,内容互不关联,这种结构下,每个站点各自积累SEO权重,适合需要大量外链或分散风险的场景,推广不同产品时,泛站能避免单一站点被处……

    2026-07-26
    0
  • 服务器防火墙硬件和软件哪个效果更好,怎么选

    在服务器防火墙的选型中,硬件防火墙与软件防火墙并非非此即彼,而是互补关系,对于追求高安全等级与稳定性的生产环境,采用硬件防火墙做网络层隔离,配合软件防火墙做主机层加固,是当前公认效果最好的组合方案,硬件防火墙与软件防火墙的核心差异性能与资源占用硬件防火墙依托专用ASIC芯片或FPGA处理数据包,转发延迟通常在微……

    2026-07-26
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注