教程 > ES6 教程 > ES6 高级 阅读:20

ES6 类

面向对象是一种遵循真实世界建模的软件开发范例。 面向对象,将程序视为对象的集合,这些对象通过称为方法的机制相互通信。 ES6 也支持这些面向对象的组件。

面向对象的编程概念

首先,让我们了解

  • 对象 - 对象是任何实体的实时表示。 根据 Grady Brooch 的说法,每个物体都具有 3 个特征 -
  • State - 由对象的属性描述。
  • 行为 - 描述对象将如何行动。
  • Identity - 将一个对象与一组类似的对象区分开来的唯一值。
  • 类 - 就 OOP 而言,类是创建对象的蓝图。 类封装对象的数据。
  • 方法 - 方法促进对象之间的通信。

让我们将这些面向对象的概念转化为现实世界中的概念。 例如:汽车是具有数据(品牌、型号、车门数量、车辆编号等)和功能(加速、换档、开门、打开前灯等)的对象

在 ES6 之前,创建类是一件繁琐的事情。 可以使用 ES6 中的 class 关键字创建类。

可以通过声明或使用类表达式将类包含在代码中。

语法:声明一个类

class Class_name {  
}

语法:类表达式

var var_name = new Class_name {  
} 

类关键字后跟类名。 命名类时必须考虑标识符规则(已经讨论过)。

类定义可以包括以下内容 -

  • 构造函数- 负责为类的对象分配内存。
  • Functions - 函数表示一个对象可以采取的行动。 它们有时也被称为方法。

这些组件放在一起称为类的数据成员。

注意 - 类主体只能包含方法,但不能包含数据属性。

示例:声明一个类

class Polygon { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

示例:类表达式

var Polygon = class { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

上面的代码片段表示一个未命名的类表达式。 命名类表达式可以写成。

var Polygon = class Polygon { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

注意 - 与变量和函数不同,类不能被提升。


创建对象

要创建类的实例,请使用 new 关键字后跟类名。 以下是相同的语法。

var object_name= new class_name([ arguments ]) 
  • new 关键字负责实例化。
  • 表达式的右侧调用构造函数。 如果构造函数被参数化,则应为其传递值。

示例 实例化一个类

var obj = new Polygon(10,12)

访问函数

可以通过对象访问类的属性和函数。 使用 . 点符号(称为句点)访问类的数据成员。

// 访问函数
obj.function_name()

示例

'use strict' 
class Polygon { 
   constructor(height, width) { 
      this.h = height; 
      this.w = width;
   } 
   test() { 
      console.log("The height of the polygon: ", this.h) 
      console.log("The width of the polygon: ",this. w) 
   } 
} 

//creating an instance  
var polyObj = new Polygon(10,20); 
polyObj.test();      

上面给出的示例声明了一个类“Polygon”。 该类的构造函数有两个参数——分别是高度和宽度。 “this”关键字指的是类的当前实例。 换句话说,上面的构造函数使用传递给构造函数的参数值初始化了两个变量 h 和 w。 类中的 test() 函数,打印高度和宽度的值。

为了使脚本起作用,创建了 Polygon 类的对象。 该对象由 polyObj 变量引用。 然后通过该对象调用该函数。

成功执行上述代码后会显示以下输出。

The height of the polygon:  10 
The width of the polygon:  20 

Setters 和 Getters

Setter

当尝试设置属性的值时,将调用 setter 函数。 set 关键字用于定义 setter 函数。 定义 setter 函数的语法如下:

{set prop(val) { . . . }}
{set [expression](val) { . . . }}

prop 是要绑定到给定函数的属性的名称。 val 是变量的别名,该变量保存试图分配给属性的值。 ES6 中的表达式,可以用作绑定到给定函数的属性名称。

示例

class Student {
    constructor(rno,fname,lname){
         this.rno = rno
         this.fname = fname
         this.lname = lname
         console.log('inside constructor')
    }
    set rollno(newRollno){
         console.log("inside setter")
         this.rno = newRollno
    }
}
let s1 = new Student(101,'Sachin','Tendulkar')
console.log(s1)
//setter is called
s1.rollno = 201
console.log(s1)

上面的示例定义了一个 Student 类,它具有三个属性,即 rno、fname 和 lname。 setter 函数 rollno() 用于设置 rno 属性的值。

上面代码的输出将如下所示

inside constructor
Student {rno: 101, fname: "Sachin", lname: "Tendulkar"}
inside setter
Student {rno: 201, fname: "Sachin", lname: "Tendulkar"}

示例

以下示例显示如何将表达式用作具有设置函数的属性名称。

let expr = 'name';
    let obj = {
    fname: 'Sachin',
    set [expr](v) { this.fname = v; }
};
console.log(obj.fname);
obj.name = 'John';
console.log(obj.fname);

上述代码的输出将如下所述

Sachin
John

Getters

当试图获取属性的值时,将调用 getter 函数。 get 关键字用于定义 getter 函数。 下面给出了定义 getter 函数的语法

{get prop() { ... } }
{get [expression]() { ... } }
  • prop 是要绑定到给定函数的属性的名称。
  • expression - 从 ES6 开始,我们还可以使用表达式作为属性名称来绑定到给定的函数。
class Student {
    constructor(rno,fname,lname){
         this.rno = rno
         this.fname = fname
         this.lname = lname
         console.log('inside constructor')
    }
    get fullName(){
         console.log('inside getter')
         return this.fname + " - "+this.lname
    }
}
let s1 = new Student(101,'Sachin','Tendulkar')
console.log(s1)
//getter is called
console.log(s1.fullName)

上面的示例定义了一个 Student 类,它具有三个属性,即 rno、fname 和 lname。 getter 函数 fullName() 连接 fname 和 lname 并返回一个新字符串。

上述代码的输出如下所示

inside constructor
Student {rno: 101, fname: "Sachin", lname: "Tendulkar"}
inside getter
Sachin - Tendulkar

示例

以下示例显示如何使用表达式作为具有 getter 函数的属性名称

let expr = 'name';
let obj = {
    get [expr]() { return 'Sachin'; }
};
console.log(obj.name);

上面代码的输出将如下所述

Sachin

Static 关键字

static 关键字可以应用于类中的函数。 静态成员由类名引用。

'use strict' 
class StaticMem { 
   static disp() { 
      console.log("Static Function called") 
   } 
} 
StaticMem.disp() // 调用静态方法

注意 - 不强制包含构造函数定义。 默认情况下,每个类都有一个默认构造函数。

成功执行上述代码后会显示以下输出。

Static Function called

instanceof 运算符

如果对象属于指定类型,则 instanceof 运算符返回 true。

'use strict' 
class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log(" obj is an instance of Person " + isPerson); 

成功执行上述代码后会显示以下输出。

obj is an instance of Person True 

类继承

ES6 支持继承的概念。 继承是程序从现有实体(这里是类)创建新实体的能力。 扩展以创建更新类的类称为父类/超类。 新创建的类称为子类/子类。

一个类使用“extends”关键字从另一个类继承。 子类从父类继承除构造函数之外的所有属性和方法。

以下是相同的语法。

class child_class_name extends parent_class_name

示例

'use strict' 
class Shape { 
   constructor(a) { 
      this.Area = a
   } 
} 
class Circle extends Shape { 
   disp() { 
      console.log("Area of the circle:  "+this.Area) 
   } 
} 
var obj = new Circle(223); 
obj.disp() 

上面的示例声明了一个类 Shape。 该类由 Circle 类扩展。 由于类之间存在继承关系,因此子类(即 Circle 类)可以隐式访问其父类属性,即 area。

成功执行上述代码后会显示以下输出。

Area of Circle: 223

承可以归类为 -

  • Single - 每个类最多可以从一个父类扩展。
  • Multiple - 一个类可以继承自多个类。 ES6 不支持多重继承。
  • 多层次 - 考虑以下示例。
'use strict' 
class Root { 
   test() { 
      console.log("call from parent class") 
   } 
} 
class Child extends Root {} 
class Leaf extends Child   

// 通过继承{}间接继承自Root
var obj = new Leaf();
obj.test() 

Leaf 类通过多级继承从 Root 类和 Child 类派生属性。

成功执行上述代码后会显示以下输出。

call from parent class

类继承和方法覆盖

方法覆盖 是子类重新定义超类方法的一种机制。 以下示例说明了相同的

'use strict' ;
class PrinterClass { 
   doPrint() { 
      console.log("doPrint() from Parent called… ");
   }
}
class StringPrinter extends PrinterClass { 
   doPrint() { 
      console.log("doPrint() is printing a string…"); 
   } 
} 
var obj = new StringPrinter(); 
obj.doPrint();

在上面的示例中,子类更改了超类函数的实现。

成功执行上述代码后会显示以下输出。

doPrint() is printing a string… 

Super 关键字

ES6 允许子类调用其父类数据成员。 这是通过使用 super 关键字实现的。 super 关键字用于引用类的直接父类。

考虑以下示例

'use strict' 
class PrinterClass { 
   doPrint() {
      console.log("doPrint() from Parent called…") 
   } 
}  
class StringPrinter extends PrinterClass { 
   doPrint() { 
      super.doPrint() 
      console.log("doPrint() is printing a string…") 
   } 
} 
var obj = new StringPrinter() 
obj.doPrint()

StringWriter 类中的 doPrint() 重新定义,发出对其父类版本的调用。 换句话说,super 关键字用于调用父类 PrinterClass 中的 doPrint() 函数定义。

成功执行上述代码后会显示以下输出。

doPrint() from Parent called. 
doPrint() is printing a string. 

查看笔记

扫码一下
查看教程更方便