现代javascript类

We often need to create many objects of the same kind, like users or cars. In object-oriented languages, a class is often used for this purpose.JavaScript, being a prototype-based language, has something called constructor functions.

我们经常需要创建许多相同种类的对象,例如用户或汽车。 在面向对象的语言中,通常为此目的使用一个类。JavaScript是一种基于原型的语言,具有一种称为构造函数的函数

// ES5 constructor function
function Car(brand) {
this.brand = brand;
}// Adding a method to the prototype
Car.prototype.getBrand = function() {
return this.brand;
}

Classes, introduced with ES6 provide “syntactical sugar”, that is comparable to inheritance in object-oriented languages. Classes are special functions meant to mimic the class keyword from these other languages. In this article we go through how to use JavaScript classes.

ES6引入的类提供“语法糖”,与面向对象语言中的继承相当。 类是特殊功能,旨在模仿其他语言的class关键字。 在本文中,我们介绍了如何使用JavaScript类。

定义班级 (Defining a Class)

To define a class we use the class keyword followed by the name of the class. The body of a class is the part that is in curly braces {}:

要定义一个类,我们使用class关键字,后跟class的名称。 类的主体是大括号{}

class Car {
// Body of the class
}

The code above defines a class Car. This syntax is named class declaration.

上面的代码定义了Car类。 此语法称为类声明

The new operator instantiates the class:

new运算符实例化该类:

const myCar = new Car();

This is how we create a new object, an instance, of the Car class.

这就是我们创建Car类的新对象( 实例 )的方式。

console.log(typeof Car); // -> function

And as you can see, in JavaScript, a class is a kind of function.

如您所见,在JavaScript中,类是一种函数。

We don’t need to give the class a name. By using a class expression you can assign the class to a variable:

我们不需要给班级起一个名字。 通过使用类表达式,您可以将类分配给变量:

const Car = class {} // unnamed
const Car = class Car {} // named

Class expressions can be named or unnamed. The name given to a named class expression is local to the class’s body.

类表达式可以命名或不命名。 命名类表达式的名称是该类主体的局部名称。

吊装 (Hoisting)

An important difference between function declarations and class declarations is that function declarations are hoisted and class declarations are not. Therefore you need to first declare the class before you can initialize objects with the `new` keyword.

函数声明和类声明之间的重要区别在于,函数声明是悬挂的,而类声明不是。 因此,您需要先声明该类,然后才能使用`new`关键字初始化对象。

Conceptually, for example, a strict definition of hoisting suggests that variable and function declarations are physically moved to the top of your code, but this is not in fact what happens. Instead, the variable and function declarations are put into memory during the compile phase, but stay exactly where you typed them in your code. — MDN

例如,从概念上讲,对提升的严格定义表明,变量和函数声明实际上已移到代码的顶部,但这实际上不会发生。 而是在编译阶段将变量和函数声明放入内存中,但仍保留在代码中键入它们的位置。 — MDN

As you might remember variables declared with var are also hoisted. So, keeping with the “modern” way it makes then sense that classes just like variables declared with let or const are not hoisted.

您可能还记得用var声明的变量也被提升了 。 因此,保持“现代”方式可以使类(就像用letconst声明的变量一样)不被提升

初始化 (Initialization)

Classes in JavaScript have a special method called constructor that lets us set initial values for fields when the object is initialized. There can be only one constructor method.

JavaScript中的类具有一个称为构造函数的特殊方法,该方法使我们可以在初始化对象时为字段设置初始值。 只能有一个构造方法

Let’s create a Car class with a constructor that sets the initial value of the field brand:

让我们创建一个带有构造器的Car类,该构造器设置字段brand的初始值:

class Car {
constructor(brand) {
this.brand = brand;
}
}

The expression this.brand = brand creates a public field brand and assigns it an initial value. We can now create a new car object and access it’s brand property:

表达式this.brand = brand创建一个公共领域 brand并为其分配初始值。 现在,我们可以创建一个新的汽车对象并访问其品牌属性

const car = new Car('Volvo');
console.log(car.brand); // -> Volvo

As you can see we can now access the brand field using a property accessor. There’s no restriction on the access of the public fields. You can read and modify the values of public fields inside the constructor, methods, and outside of the class.

如您所见,我们现在可以使用属性访问器访问brand字段。 对公共领域的访问没有任何限制。 您可以在构造函数,方法内部以及类外部读取和修改公共字段的值。

The bodies of class declarations and class expressions are executed in strict mode.

类声明和类表达式的主体以严格模式执行。

方法 (Methods)

Classes provide a cleaner and more elegant syntax for adding methods.

类为添加方法提供了更简洁,更优雅的语法。

class Car { 
constructor(brand) {
this.brand = brand;
} getBrand() {
return this.brand;
}
}

The keyword this allows us to access instance data inside the constructor and methods.

关键字this允许我们访问构造函数和方法内部的实例数据。

const car = new Car('Tesla');
console.log(car.getBrand()); // -> Tesla

The method invocation car.getBrand() executes the methods inside the Car class and returns the brand property.

方法调用car.getBrand()在Car类内部执行方法,并返回brand属性。

静态方法 (Static Methods)

We can also assign a method to the class function itself, not to its prototype. Such methods are called static and are prepended with the static keyword:

我们还可以将方法分配给类函数本身,而不是其原型 。 此类方法称为static ,并带有static关键字:

class Double {
static double(n) {
return n * 2;
}
}Double.double(2); // -> 4

We don’t have to create an instance of the class but can call the method directly on the class itself. Static methods are often used in utility classes for making computations.

我们不必创建类的实例,但是可以直接在类本身上调用该方法。 静态方法通常在实用程序类中用于进行计算。

吸气剂和二传手 (Getters and Setters)

JavaScript classes can have getter and setter functions.

JavaScript类可以具有getter和setter函数。

class Car { 
constructor(brand) {
this.brand = brand;
} get brand() {
return this._brand;
} set brand(value) {
this._brand = value;
}
}

Notice that if you would do this.brand = value in the setter we would be calling the setter again and go into an infinite loop. Using an underscore _ is a common convention.

请注意,如果您要在设置器中执行this.brand = value ,我们将再次调用设置器并进入无限循环。 通常使用下划线_

With this we can create an instance of the class and access the brand property through the setter and getter:

这样,我们可以创建类的实例,并通过设置器和获取器访问brand属性:

const car = new Car('');
car.brand = 'Tesla;
console.log(car.brand); // -> Tesla

遗产 (Inheritance)

Class inheritance is a way to inherit the functionality of another class and extend it. We create a child class with the extends keyword.

类继承是一种继承另一个类的功能并对其进行扩展的方法。 我们使用extends关键字创建一个子类。

class SportsCar extends Car {
isFast() {
return true;
}
}

Now we can use the functionality of the class we extended:

现在,我们可以使用扩展的类的功能:

const car = new SportsCar('Mazda');
console.log(car.brand); // -> Mazda
console.log(car.isFast()); // -> true

You can see here that we didn’t have to create a constructor. If a class extends another class and has no constructor, then the following constructor is generated:

您可以在此处看到我们不必创建构造函数。 如果一个类扩展了另一个类并且没有构造函数,那么将生成以下构造函数:

constructor(...args) {
super(...args); // Copying args with spread operator (...)
}

The super keyword is used to call corresponding methods of the parent class. So the constructor calls the parent constructor passing it all the arguments. If we want to add another in-parameter to our class we can create a constructor:

super关键字用于调用父类的相应方法。 因此,构造函数调用父构造函数,并为其传递所有参数。 如果我们想在类中添加另一个参数,则可以创建一个构造函数:

class SportsCar extends Car {
constructor(brand, model) {
super(brand);
this.model = model;
}
}const myCar = new SportsCar('Mazda', 'MX-5');

Note that constructors in inheriting classes must call super(), and do it before using this.

请注意,继承类中的构造函数必须调用super() ,并在使用this之前进行this

结论 (Conclusion)

  • Use classes when you need to create multiple objects of the same kind.

    当您需要创建相同种类的多个对象时,请使用类。

  • Classes are a special kind of functions that run in strict mode and are not hoisted.

    类是一种特殊的功能,它在严格模式下运行并且不被提升

  • Classes can have fields and methods that we can access from a class instance.

    类可以具有我们可以从类实例访问的字段和方法。
  • We can inherit functionality from other classes by extending them.

    我们可以通过扩展其他类来继承它们的功能。

翻译自: https://medium.com/@michael.karen/modern-javascript-classes-cec93045d85d

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值