📅  最后修改于: 2020-10-25 10:43:58             🧑  作者: Mango
面向对象是遵循真实世界建模的软件开发范例。面向对象,将程序视为对象的集合,这些对象通过称为方法的机制相互通信。 ES6也支持这些面向对象的组件。
首先,让我们了解
对象-对象是任何实体的实时表示。根据Grady Brooch的说法,每个对象都具有3个特征-
状态-由对象的属性描述。
行为-描述对象的行为。
身份-唯一值,将一个对象与一组类似的对象区分开。
类-就OOP而言,类是创建对象的蓝图。一个类封装对象的数据。
方法-方法有助于对象之间的通信。
让我们将这些面向对象的概念转换为现实世界中的概念。例如:汽车是具有数据(品牌,型号,门数,车号等)和功能(加速,变速,开门,打开大灯等)的对象。
在ES6之前,创建课程是一件大事。可以使用ES6中的class关键字创建类。
可以通过声明类或使用类表达式将类包含在代码中。
class Class_name {
}
var var_name = new Class_name {
}
class关键字后跟类名称。命名类时必须考虑标识符规则(已经讨论过)。
类定义可以包括以下内容-
构造函数-负责为类的对象分配内存。
功能-功能代表对象可以采取的行动。它们有时也称为方法。
这些组件放在一起称为类的数据成员。
注–类主体只能包含方法,而不能包含数据属性。
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)
可以通过对象访问类的属性和函数。使用 ‘。’点表示法(称为句点)以访问类的数据成员。
//accessing a function
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();
上面给出的示例声明了一个“多边形”类。该类的构造函数采用两个参数-分别为height和width。 “ this”关键字引用该类的当前实例。换句话说,上面的构造函数使用传递给构造函数的参数值初始化两个变量h和w。该类中的test()函数输出高度和宽度的值。
为了使脚本起作用,创建了Polygon类的对象。该对象由polyObj变量引用。该函数,然后通过这个对象调用。
成功执行上述代码后,将显示以下输出。
The height of the polygon: 10
The width of the polygon: 20
尝试设置属性值时,将调用setter函数。 set关键字用于定义setter函数。下面给出了用于定义setter函数的语法-
{set prop(val) { . . . }}
{set [expression](val) { . . . }}
prop是绑定到给定函数的属性的名称。 val是变量的别名,该变量保存试图分配给属性的值。 ES6中的表达式可以用作绑定到给定函数的属性名称。
上面的示例定义了一个Student类,它具有rno,fname和lname三个属性。设置器函数rollno()用于设置rno属性的值。
上面代码的输出将如下所示-
inside constructor
Student {rno: 101, fname: "Sachin", lname: "Tendulkar"}
inside setter
Student {rno: 201, fname: "Sachin", lname: "Tendulkar"}
下面的示例演示如何通过setter函数将表达式用作属性名称。
上面代码的输出将如下所述-
Sachin
John
尝试获取属性值时,将调用getter函数。 get关键字用于定义getter函数。下面给出了定义getter函数的语法-
{get prop() { ... } }
{get [expression]() { ... } }
prop是绑定到给定函数的属性的名称。
expression-从ES6开始,还可以将表达式用作属性名称以绑定到给定的函数。
上面的示例定义了一个Student类,它具有rno,fname和lname三个属性。 getter函数fullName()连接fname和lname并返回一个新的字符串。
上面代码的输出如下:
inside constructor
Student {rno: 101, fname: "Sachin", lname: "Tendulkar"}
inside getter
Sachin - Tendulkar
以下示例显示如何使用带有getter函数的表达式作为属性名称-
上面代码的输出将如下所述-
Sachin
可以将static关键字应用于类中的函数。静态成员由类名称引用。
'use strict'
class StaticMem {
static disp() {
console.log("Static Function called")
}
}
StaticMem.disp() //invoke the static metho
注–并非必须包含构造函数定义。默认情况下,每个类都有默认的构造函数。
成功执行上述代码后,将显示以下输出。
Static Function called
如果对象属于指定的类型,则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
继承可以分类为-
单个-每个类最多只能从一个父类扩展。
多个-一个类可以从多个类继承。 ES6不支持多重继承。
多层-考虑以下示例。
'use strict'
class Root {
test() {
console.log("call from parent class")
}
}
class Child extends Root {}
class Leaf extends Child
//indirectly inherits from Root by virtue of inheritance {}
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…
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.