JavaScript 类与原型 - 组织 JavaScript 代码
作者:互联网
关于JavaScript语言的故事非常有趣。对于那些不知道的人,以下是流行的多范式语言的一些亮点:
-
Brendan Eich(@BrendanEich)是Netscape Communications Corporation的程序员,在10年仅用了1995天就创建了Mocha。
-
Mocha 很快被命名为 JavaScript——它与 Java 完全无关——很可能是一种利用 Java 流行度的营销方法。
-
JavaScript 是作为在网站大多是静态的时代提供动态编程体验的一种选择而引入的。
-
自 1996 年以来,ECMAScript 语言规范 (ECMA-262) 定义并标准化了 JavaScript 语言,现在是第 11 版。
-
JavaScript 运行在全球大约 97% 的浏览器上。
-
JavaScript已经成为Angular,React和Vue.js等客户端框架以及Node运行时.js的首选。
自从 JavaScript 成为主流以来,我一直参与过以这样或那样的方式使用 JavaScript 的项目。在早期,JavaScript 被 HTML 文件引用,以便在将请求发送到后端服务之前执行简单的验证。现在,我在过去 7 年中参与的每个基于 Web 的项目都使用完全使用 JavaScript 构建的客户端框架。
然而,JavaScript 并非没有设计挑战,我在 2017 年 <> 月的出版物《JavaScript 会通过时间的考验吗?》中指出了这一点。
当时没有提到的项目之一是讨论何时使用类以及何时在 JavaScript 中使用原型。我本文的目标是重点介绍这些概念,即使使用现有框架,如 Salesforce Lightning Web Components (LWC)。
JavaScript 中的原型概念
出于本文的目的,最好先讨论 JavaScript 中的原型概念。
在 JavaScript 中,所有对象都从原型继承属性和方法。让我们考虑以下原型示例:
JavaScript1
function Vehicle(vinNumber, manufacturer, productionDate, fuelType) {
2
this.manufacturer = manufacturer;
3
this.vinNumber = vinNumber;
4
this.productionDate = productionDate;
5
this.fuelType = fuelType;
6
}
7
8
Vehicle.prototype.vehicleInformation = function() {
9
var productionDate = new Date(this.productionDate * 1000);
10
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
11
var year = productionDate.getFullYear();
12
var month = months[productionDate.getMonth()];
13
var day = productionDate.getDate();
14
15
var friendlyDate = month + ' ' + day + ', ' + year;
16
return this.manufacturer + ' vehicle with VIN Number = ' + this.vinNumber + ' was produced on ' + friendlyDate + ' using a fuel type of ' + this.fuelType;
17
}
作为此代码的结果,有一个对象可用,可以使用以下代码创建新实例:Vehicle
1
let rogue = new Vehicle('5N1FD4YXN11111111', 'Nissan', 1389675600, 'gasoline');
有了这些信息,就可以使用以下方法调用该函数:vehicleInformation()
1
alert(rogue.vehicleInformation());
这将生成一个包含以下消息的警报对话框:
“VIN 编号 = 5N1FD4YXN11111111 的日产车辆于 14 年 2014 月 <> 日使用汽油燃料生产”
正如人们所期望的那样,可以引入第二个原型来进一步定义给定类型的车辆:SportUtilityVehicle
1
function SportUtilityVehicle(vinNumber, manufacturer, productionDate, fuelType, drivetrain) {
2
Vehicle.call(this, vinNumber, manufacturer, productionDate, fuelType);
3
this.drivetrain = drivetrain;
4
}
现在,我们可以新建一个而不是简单的.SportUtilityVehicle
Vehicle
1
let rogue = new SportUtilityVehicle('5N1FD4YXN11111111', 'Nissan', 1389675600, 'gasoline', 'AWD');
我们还可以使用原型定义一个新版本:SportUtilityVehicle
1
SportUtilityVehicle.prototype.vehicleInformation = function() {
2
return this.manufacturer + ' vehicle with VIN Number = ' + this.vinNumber + ' utilizes drivetrain = ' + this.drivetrain + ' and runs on ' + this.fuelType;
3
}
现在,当使用以下方法调用函数时:vehicleInformation()
1
alert(rogue.vehicleInformation());
将出现一个警报对话框,其中包含以下消息:
“VIN 号 = 5N1FD4YXN11111111 的日产车辆使用传动系统 = AWS 并使用汽油运行”
JavaScript 类
从 ECMAScript 2015(6 年 2015 月作为第 <> 版发布)开始,JavaScript 引入了类的概念。虽然这可能会激起使用 Java、C# 和 C++ 等语言的开发人员的兴趣,但引入类选项的目标是允许使用更简单、更干净的语法创建类。事实上,文档继续指出类只是“语法糖”,以使开发人员更容易。
将前面的示例从原型转换为类将如下所示:
JavaScript1
class Vehicle {
2
constructor(vinNumber, manufacturer, productionDate, fuelType) {
3
this.manufacturer = manufacturer;
4
this.vinNumber = vinNumber;
5
this.productionDate = productionDate;
6
this.fuelType = fuelType;
7
}
8
9
vehicleInformation() {
10
var productionDate = new Date(this.productionDate * 1000);
11
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
12
var year = productionDate.getFullYear();
13
var month = months[productionDate.getMonth()];
14
var day = productionDate.getDate();
15
16
var friendlyDate = month + ' ' + day + ', ' + year;
17
return this.manufacturer + ' vehicle with VIN Number = ' + this.vinNumber + ' was produced on ' + friendlyDate + ' using a fuel type of ' + this.fuelType;
18
}
19
}
20
21
class SportUtilityVehicle extends Vehicle {
22
constructor(vinNumber, manufacturer, productionDate, fuelType, drivetrain) {
23
super(vinNumber, manufacturer, productionDate, fuelType);
24
this.drivetrain = drivetrain;
25
}
26
27
vehicleInformation() {
28
return this.manufacturer + ' vehicle with VIN Number = ' + this.vinNumber + ' utilizes drivetrain = ' + this.drivetrain + ' and runs on ' + this.fuelType;
29
}
30
}
如果我们需要在类中添加 getter 和 setter,可以更新类,如下所示:SportUtilityVehicle
1
class SportUtilityVehicle extends Vehicle {
2
constructor(vinNumber, manufacturer, productionDate, fuelType, drivetrain) {
3
super(vinNumber, manufacturer, productionDate, fuelType);
4
this.drivetrain = drivetrain;
5
}
6
7
vehicleInformation() {
8
return this.manufacturer + ' vehicle with VIN Number = ' + this.vinNumber + ' utilizes drivetrain = ' + this.drivetrain + ' and runs on ' + this.fuelType;
9
}
10
11
get drivetrain() {
12
return this._drivetrain;
13
}
14
15
set drivetrain(newDrivetrain) {
16
this._drivetrain = newDrivetrain;
17
}
18
}
如您所见,语法类似于 Java 或 C# 等语言。类方法还允许属于原型链的函数和属性不引用 Object.prototype 语法。一个要求是构造函数始终称为“构造函数”。
JavaScript Class v Prototype
如上所述,JavaScript 中的类只是语法糖,以使使用 JavaScript 的功能开发人员更容易。虽然这种方法允许那些来自Java,C#或C++等语言的人进行更常见的设计,但许多Javascript纯粹主义者建议不要使用类。
事实上,Michael Krasnov 在“请停止在 JavaScript 中使用类”一文中提到了一个令人担忧的问题:
绑定问题。由于类构造函数密切处理此关键字,因此可能会引入潜在的绑定问题,尤其是在尝试将类方法作为回调传递给外部例程时。
Michael接着提出了避免使用Javascript类的其他四个原因,但是类选项的倡导者很快就减轻了他的思想。
从 2021 年开始,我一直坚持以下任何 IT 专业人员的使命宣言:
“将您的时间集中在提供扩展您的知识产权价值的特性/功能上。利用框架、产品和服务完成其他所有工作。
当谈到在 JavaScript 中使用类或原型时,我觉得这是一个应该由支持和维护代码库的团队做出的决定。如果他们的舒适度在遵循原型方法后没有问题,那么他们应该相应地设计他们的组件。但是,如果偏好是利用类概念,则该团队的开发人员应该了解上述绑定挑战,但应该继续前进并保持在他们的舒适区内。
对闪电网络组件的影响
Salesforce几年前推出了Lightning Web Components(LWC),我在“Salesforce Offer JavaScript Programming Model”一文中谈到了这一点。将近三年后,我发现自己在谈论使用类和原型方法对Salesforce开发人员的影响。
快速的答案是...这不重要。Salesforce允许Lightning Web Components利用原型或类。JavaScript的典型继承模型是通过原型。但是为了吸引习惯于经典继承的开发人员,可以使用这种语法糖来帮助开发人员通过使用看起来非常像经典继承的方法来实现原型继承。
因此,当涉及到 LWC 时——这完全是关于继承的,因为 LWC 已经构建了一个很棒的基类组件供您扩展——你也可以利用这种语法糖。
你不需要担心原型遗传,即使这一切都发生在幕后。只要做经典的继承,你就是金子。
下面是一个示例:
JavaScript1
import { LightningElement } from 'lwc';
2
3
export default class VehicleComponent extends LightningElement {
4
// properties go here
5
6
vehicleInformation() {
7
return this.manufacturer + ' vehicle with VIN Number = ' + this.vinNumber + ' utilizes drivetrain = ' + this.drivetrain + ' and runs on ' + this.fuelType;
8
}
9
}
标签:JavaScript,Java,代码 来源: