javascript学习_学习JavaScript类简介(第1部分)

javascript学习

JavaScript has not always had the ability to create classical objects as can be created in languages such as C++ and Java, but you can now since the development of EcmaScript 6. In this article I’m going to introduce how to create classes in JavaScript, including how to implement constructors and accessor methods (getters and setters) I’ll cover other aspects of JavaScript classes in future articles.

JavaScript并不总是能够像在C ++和Java之类的语言中那样创建经典对象,但是从EcmaScript 6的开发开始,您现在就可以了。在本文中,我将介绍如何在JavaScript中创建类,包括如何实现构造函数和访问器方法(getter和setter),我将在以后的文章中介绍JavaScript类的其他方面。

EcmaScript 6之前的类 (Classes Before EcmaScript 6)

In previous versions of JavaScript (EcmaScript), you could not create a class in the way you can in languages such as C++ and Java. Instead, you had to create a constructor function and then assign methods to the constructor’s prototype. The following example demonstrates this technique:

在早期版本JavaScript(EcmaScript)中,您无法以诸如C ++和Java之类的语言创建类。 相反,您必须创建一个构造函数,然后将方法分配给构造函数的原型。 下面的示例演示了此技术:

function Student(name, id, grades) {
this.name = name;
this.id = id;
this.grades = grades;
}Student.prototype.calcAverage = function() {
let sum = 0;
for (grade of this.grades) {
sum += grade;
}
return sum / this.grades.length;
}let stu1 = new Student("Jane Smith", 1234, [81, 77, 92]);
print("Grade average: " + stu1.calcAverage());
// displays 83.33333333333

This is not how classical object-oriented programming (OOP) languages define class objects and methods, but it was the nearest way to do it in previous versions of JavaScript.

这不是经典的面向对象程序设计(OOP)语言定义类对象和方法的方式,而是在早期JavaScript版本中最接近的方法。

立即在JavaScript中创建类 (Creating Classes in JavaScript Now)

The current version of JavaScript now allows you to create classes that are more closely related to how classical OOP languages create them. Let’s start by seeing how we can define the student example above as a class:

现在,当前版本JavaScript允许您创建与经典OOP语言创建它们的方式更紧密相关的类。 让我们从如何将上面的学生示例定义为类开始:

class Student {  constructor(name, id, grades) {
this.name = name;
this.id = id;
this.grades = grades;
}
calcAverage() {
let sum = 0;
for (let grade of this.grades) {
sum += grade;
}
return sum / this.grades.length;
}
}let stu1 = new Student("Jane Smith", 1234, [81, 77, 92]);
print("Grade average: " + stu1.calcAverage());

The output of this program is:

该程序的输出为:

Grade average: 83.33333333333

The class definition looks much more like the way it is done in other OOP languages. The keyword class indicates a class definition is coming up. A constructor is created, not with the class name, but with the keyword constructor. Nonetheless, as you can see in the example program, the constructor function is still called using the class name.

类定义看起来更像其他OOP语言中的定义。 关键字class表示即将出现类定义。 创建的构造函数不是使用类名,而是使用关键字constructor 。 但是,如您在示例程序中看到的那样,仍使用类名来调用构造函数。

类定义是语法糖 (Class Definitions are Syntactic Sugar)

A class definition is just syntactic sugar that hides the standard way object prototypes are created in JavaScript. This means that I could have defined the Student class above using older JavaScript object syntax, like this (this example is modified from an example in the book Understanding EcmaScript 6 by Nicholas C. Zakas on page 168):

类定义只是语法糖,它隐藏了在JavaScript中创建对象原型的标准方式。 这意味着我可以使用较旧JavaScript对象语法定义上面的Student类,如下所示(此示例是由Nicholas C. Zakas在第168页的《 理解EcmaScript 6 》一书中的示例进行修改):

let Student = function(name, id, grades) {
"use strict";
const Student = function(name, id, grades) {
if (typeof new.target === "undefined") {
throw new Error("Constructor must be called with new.");
}
this.name = name;
this.id = id;
this.grades = grades;
} Object.defineProperty(Student.prototype, "calcAverage", {
value: function() {
if (typeof new target !== "undefined") {
throw new Error("Method cannot be called with new.");
}
let sum = 0;
for (let grade of this.grades) {
sum += grade;
}
return sum / this.grades.length;
},
enumerable: false,
writable: true,
configurable: true
});
return Student;
}());

Clearly, the class syntax makes creating classes a lot easier than doing it the old way.

显然,与旧方法相比,类语法使创建类容易得多。

There are a couple of things to notice here, though. First, all the code inside a class definition runs in strict mode by default. Also, all methods are defined as nonenumerable by default. Class methods cannot be called with the new keyword, but class constructors must be called with the new keyword.

不过,这里有几件事要注意。 首先,默认情况下,类定义中的所有代码都以严格模式运行。 同样,默认情况下,所有方法都定义为无数。 不能使用new关键字调用类方法,但是必须使用new关键字调用类构造函数。

Generally, this new JavaScript syntax for creating classes give you lots of functionality without having to write the more complicated object-based syntax necessary in previous JavaScript versions.

通常,这种用于创建类的新JavaScript语法为您提供了许多功能,而无需编写先前JavaScript版本中所需的更为复杂的基于对象的语法。

类构造器 (Class Constructors)

As shown in the examples above, classes need to be instantiated with a constructor. Here is another class definition with a constructor defined:

如以上示例所示,需要使用构造函数实例化类。 这是定义了构造函数的另一个类定义:

class Person {
constructor(name, age) {
this.name = name;
this.age = age;
} show() {
return this.name + ", " + this.age;
}
}

If you don’t define a constructor, the system will provide you with a default constructor automatically. Here’s an example that demonstrates this:

如果未定义构造函数,则系统将自动为您提供默认的构造函数。 这是一个演示此的示例:

class Person {
show() {
return this.name + ", " + this.age;
}
}let you = new Person();
print(you.show());

The output from this program is:

该程序的输出为:

undefined, undefined

Even though I didn’t define a constructor method, the program did not crash because a default constructor was created and assigned undefined to name and age.

即使我没有定义构造函数方法,程序也不会崩溃,因为创建了默认构造函数并将undefined分配给nameage

You cannot define a default constructor if you already have another constructor defined. Classes are allowed just one constructor definition, or, to put it another way, they are allowed one use of the constructor keyword. The system provides the default constructor when either there are no constructors defined or another constructor is already defined.

如果已经定义了另一个构造函数,则无法定义默认构造函数。 只允许类使用一个构造函数定义,或者换句话说,允许类一次使用constructor关键字。 当未定义构造函数或已经定义另一个构造函数时,系统将提供默认构造函数。

存取器属性 (Accessor Properties)

A complete class definition provides accessor methods (or properties in JavaScript’s case) for retrieving and setting property values. These are often called getters and setters in OOP languages.

完整的类定义提供用于获取和设置属性值的访问器方法(或JavaScript情况下的属性)。 在OOP语言中,这些通常称为getter和setter。

Let’s start with getting a current property. The keyword to use in the definition is get. This property simply returns the value stored in the property. Here is the Person class definition with a getter property:

让我们从获取当前属性开始。 在定义中使用的关键字是get 。 该属性仅返回存储在该属性中的值。 这是带有getter属性的Person类定义:

class Person {
constructor(name, age) {
this.name = name;
this.pAge = age;
} get age() {
return this.pAge;
} show() {
return this.name + ", " + this.age;
}
}let me = new Person("John Green", 24);
print("Age: " + me.age); // displays Age: 24

Here I changed the name of the property that stores a person’s age to pAge so that I can use age as the getter property.

在这里,我将存储人的年龄的属性的名称更改为pAge以便可以将age用作getter属性。

Now let’s add a setter to the class definition. Having a setter allows you to perform some data validation when setting a property value. For example, the age property can be set to any valid number so someone’s age can be -2000 or 123,456. Let’s define the setter for age so that it only accepts values from 0 to 120.

现在让我们向类定义添加一个setter。 拥有设置器使您可以在设置属性值时执行一些数据验证。 例如, age属性可以设置为任何有效数字,因此某人的年龄可以是-2000或123,456。 让我们定义age的设置器,使其只接受0到120之间的值。

Here’s the new class definition with this setter:

这是此设置方法的新类定义:

class Person {
constructor(name, age) {
this.name = name;
if (age >= 0 && age <= 120) {
this.pAge = age;
}
else {
this.pAge = 0;
}
} get age() {
return this.pAge;
} set age(value) {
if (value >= 0 && value <= 120) {
this.pAge = value;
}
else {
this.pAge = 0;
}
} show() {
return this.name + ", " + this.age;
}
}let me = new Person("John Green", 24);
print("Age: " + me.age); // displays Age: 24
me.age = 121;
print("Age: " + me.age); // displays 0
me.age = 25;
print("Age: " + me.age); // displays Age: 25

Looking over my class definition, I also need to add this data validation code to my constructor, like this:

查看我的类定义,我还需要将此数据验证代码添加到我的构造函数中,如下所示:

constructor(name, age) {
this.name = name;
if (age >= 0 && age <= 120) {
this.pAge = age;
}
else {
this.pAge = 0;
}
}

Another solution would be to write a function for validating an age and calling the function from the constructor and the setter. I’ll leave that as an exercise for the reader.

另一个解决方案是编写一个用于验证年龄并从构造函数和setter调用该函数的函数。 我将其留给读者练习。

第二部分 (Coming Up in Part 2)

I have only scratched the surface of creating classes in JavaScript. In my next article I’ll discuss more class features, including how to treat classes as first-class objects, computed member names, and static class members. After that article, I’ll move to class inheritance in JavaScript.

我只是从头开始创建JavaScript类。 在我的下一篇文章中,我将讨论更多的类功能,包括如何将类视为一等对象,计算所得的成员名称和静态的类成员。 在那篇文章之后,我将转向JavaScript中的类继承。

Thanks for reading and please email comments and suggestions to mmmcmillan1@att.net. If you are interested in my online programming courses, visit https://learningcpp.teachable.com.

感谢您的阅读,请将评论和建议通过电子邮件发送至mmmcmillan1@att.net 。 如果您对我的在线编程课程感兴趣,请访问https://learningcpp.teachable.com

翻译自: https://levelup.gitconnected.com/learning-javascript-an-introduction-to-classes-part-1-d4c07b59ee3c

javascript学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值