JavaScript的面向对象编程
JavaScript的面向对象编程
面向对象编程 —— Object Oriented Programming,简称 OOP ,是一种编程开发思想。 它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。面向对象的特性:
封装性
继承性
多态性抽象
JavaScript的面向对象编程和大多数其他语言如Java、C#的面向对象编程都不太一样。如果你熟悉Java或C#,很好,你一定明白面向对象的两个基本概念:
类(class):类是对象的类型模板,例如,定义Student类来表示学生,类本身是一种类型,Student表示学生类型,但不表示任何具体的某个学生;
实例(Instance):实例是根据类创建的对象,例如,根据Student类可以创建出xiaoming、xiaohong、xiaojun等多个实例,每个实例表示一个具体的学生,他们全都属于Student类型。
类和实例是大多数面向对象编程语言的基本概念。
JavaScript面向对象术语
【参见 JavaScript面向对象简介 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript 术语 部分】
Namespace 命名空间
允许开发人员在一个独特,应用相关的名字的名称下捆绑所有功能的容器。
Class 类
定义对象的特征。它是对象的属性和方法的模板定义。
Object 对象
类的一个实例。
Property 属性
对象的特征,比如颜色。
【又见 Property (JavaScript) https://developer.cdn.mozilla.net/en-US/docs/Glossary/property/JavaScript
JavaScript property是对象的特征(characteristic),通常描述与数据结构相关联的attributes。
有两种属性(properties):
实例属性(Instance properties)保存特定于给定对象实例的数据。
静态属性(Static properties)保存在所有对象实例之间共享的数据。】
Method 方法
对象的能力,比如行走。
Constructor 构造函数
对象初始化的瞬间,被调用的方法。通常它的名字与包含它的类一致。
Inheritance 继承
一个类可以继承另一个类的特征。
Encapsulation 封装
一种把数据和相关的方法绑定在一起使用的方法。
Abstraction 抽象
结合复杂的继承,方法,属性的对象能够模拟现实的模型。
Polymorphism 多态
多意为「许多」,态意为「形态」。不同类可以定义相同的方法或属性。
【关于 JavaScript面向对象,可参见:适合初学者的JavaScript面向对象 https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Objects/Object-oriented_JS 】
早期的ECMAScript-262 (也称为ECMAscript)标准把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数。 严格来讲,这就相当于说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。
每个对象都是基于一个引用类型创建的,这些类型可以是系统内置的原生类型,也可以是开发人员自定义的类型。
简单地说,早期的ECMAScript-262 (ECMAscript)标准不区分类和实例的概念,而是通过原型(prototype)和构造函数Constructor)来实现面向对象编程。
【一文读懂 JavaScript 和 ECMAScript 的区别
https://www.oschina.net/translate/whats-the-difference-between-javascript-and-ecmascript?lang=chs 】
ECMAScript 6,也称为ECMAScript 2015或ECMA-262 edition 6,简称ES6,它是 ECMA-262 标准的第六个版本,其特点是对 ECMAScript 规范有着显著的变化和改进,如引进了类(class)。ES6之前,javascript本质上不能算是一门面向对象的编程语言,因为它对于封装、继承、多态这些面向对象语言的特点并没有在语言层面上提供原生的支持。它引进了原型(prototype)的概念,可以让我们以另一种方式模仿类,并通过原型链的方式实现了父类子类之间共享属性的继承以及身份确认机制。正是由于javascript本身对面向对象编程没有一个语言上的支持标准,所以才有了五花八门、令人眼花缭乱的“类继承”的代码。所幸,es6增加了class、extends、static等关键字用以在语言层面支持面向对象。我们先列举出es6之前常见的几种继承方案,然后再来一探es6的类继承机制,最后再讨论下javascript多态。
JavaScript 面向对象的设计思想是:
☆早期技术——ES6之前的方式
JavaScript 面向对象的设计思想是:
抽象出构造函数Constructor)
根据构造函数Constructor) 创建 Instance(实例)
指挥 Instance(实例) 得结果
☆新技术——引进了类(class)后的方式
抽象出 Class(类)
根据 Class(类)或创建 Instance(实例)
指挥 Instance(实例) 得结果
ES6之前
ES6之前,JavaScript中没有类的概念,创建一个对象只要定义一个该对象的构造函数并通过它创建对象即可 。
创建一个Card(名片)对象,每个对象又有这些属性:name(名字)、address(地址)、phone(电话)。创建名片对象的构造函数 代码如下:
function Card( _name, _address, _phone ) // 定义构造函数
{
this.name=\_name; // 初始化“名字”属性
this.address=\_address; // 初始化“地址”属性
this.phone=\_phone; // 初始化“电话”属性
}
用于输出卡片上的信息 的方法如下:
function printCard() //打印信息
{
line1="Name:"+this.name+"<br>\\n"; // 读取name
line2="Address:"+this.address+"<br>\\n"; // 读取address
line3="Phone:"+this.phone+"<br>\\n" // 读取phone
document.writeln(line1,line2,line3);
}
实例化对象
Tom=new Card(“张三”,”某市区广达路 123好”,”电话:0633-6668888”); // 创建名片Tom.printCard(); // 输出名片信息
完整代码如下:
<!DOCTYPE html>
保存文件名为:名片.html
运行之,按F12 打开控制台,显示如下图:
对象的废除
把对象的引用设置为null,对象就会被清除。如:
obj = null; //将obj对象清除
ES6之前,JavaScript通过模仿类实现继承,方式很多,在此进简单介绍原型继承、借用构造函数的方式继承。
原型继承的例子
// 父类
function Persion(name,age){
this.name = name;
this.age = age;
}
// 父类的原型对象属性
Persion.prototype.id = 10;
// 子类
function Boy(sex){
this.sex = sex;
}
// 继承实现
Boy.prototype = new Persion(‘c5’,27);
var b = new Boy();
console.log(b.name)// c5
console.log(b.id)//10
运行之,参见下图:
借用构造函数的方式继承的例子
// 父类
function Persion(name,age){
this.name = name;
this.age = age;
}
// 父类的原型对象属性
Persion.prototype.id = 10;
// 子类
function Boy(name,age,sex){
//call apply 实现继承
Persion.call(this,name,age);
this.sex = sex;
}
var b = new Boy(‘c5’,27,’男’);
console.log(b.name)// c5
console.log(b.id)//undinfind 父类的原型对象并没有继承
运行之,参见下图:
引进了类(class)后
新的关键字class从ES6开始正式被引入到JavaScript中。class的目的就是让定义类更简单。
JavaScript类 参考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes
我们先回顾前面用函数实现Student修改版的方法:
function Student(name) {
this.name = name;
}
Student.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
}
如果用新的class关键字来编写Student,可以这样写:
class Student {
constructor(name) \{
this.name = name;
\}
hello() \{
alert('Hello, ' + this.name + '!');
\}
}
创建一个Student对象代码和前面完全一样:
var xiaoming = new Student(‘小明’);
xiaoming.name; // “小明”
xiaoming.hello(); // Hello, 小明!
对于class的继承,直接通过extends来实现。我们从Student派生一个PrimaryStudent:
class PrimaryStudent extends Student {
constructor(name, grade) \{
super(name); // 记得用super调用父类的构造方法!
this.grade = grade;
\}
myGrade() \{
alert('I am at grade ' + this.grade);
\}
}
注意PrimaryStudent的定义也是class关键字实现的,而extends则表示原型链对象来自Student。
关于JavaScript继承与原型链可参见 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
关于ES6中的类可参见https://blog.csdn.net/weixin_43883917/article/details/110325090
就此打住,不深入介绍了。下面给出比较完整的例子
例1、早期的封装、继承与多态的例子,代码如下:
<!DOCTYPE html>
保存文件名为:早期的封装、继承与多态.html
运行之,按F12 打开控制台,显示如下图:
例2、ES6的封装、继承与多态的例子,代码如下:
<!DOCTYPE html>
保存文件名为:ES6的封装、继承与多态.html
运行之,按F12 打开控制台,显示如下图:
若想进一步学习 JavaScript 面向对象编程,可参见:
JavaScrip面向对象编程
https://www.liaoxuefeng.com/wiki/1022910821149312/1023022126220448
Javascript的继承与多态
https://www.jianshu.com/p/5cb692658704
还没有评论,来说两句吧...