JS对象进阶-理解和对象相关的概念
面向对象是一种描述代码组织架构的形式,一种在软件领域对真实世界中问题的建模方法。本文主要介绍面向对象程序设计(OOP)中的一些常见名词和概念
对象
何为对象?简单说就是事物或人物在程序设计语言中的变现形式。例如“人”可以被看做是一个对象,每个人都有名字、性别和年龄这些特征,在OOP中这些特征称为属性;每个人都会执行吃饭、睡觉和走路这些动作,在OOP中这些动作称作方法。
对象通常用名词表示(如Person,Book),方法常用动词表示(如read,sleep)。
类
相似对象间通常会有一些共同的特征,如Programmer、Designer和ProjectManager都属于人类这个大类下,都有名字、年龄和性别这些共同的特征,但他们又有各自的技能。在OOP中,类就像是一个模板,作为对象的设计图,对象就是在这些模板的基础上创建的实体。对象有时也叫做实例,所以可以把Programmer、Designer和ProjectManager看做人类的一个实例,你可以在人类的基础上扩展更多的实体。
前面提到JS这门语言是没有类、继承这些概念的,它的一切都是基于对象的。真正的面向对象的语言,你可以基于某个类创建一个新的对象,但是在JS中只能是把现有的对象扩展成一个新对象。
封装
封装就是隐藏对象中属性和方法的可见性,对外只暴露相关的接口。封装包括封装数据(即属性)和基于这些数据的方法。多数传统的面向对象语言,都会提供一些关键字(如public、private、protected)用于限制属性和方法的可见性,但JS没有提供这些,只能依赖变量的作用域实现类似封装的效果。如果不考虑ES6,通常使用函数创建独立作用域。
var obj = (function(){
var name = 'li'; // private 变量
return {
sayName: function(){ // public 方法
return name;
}
}
})();
console.log(obj.sayName()); // 'li'
console.log(obj.name); // undefined
面向对象的程序设计强调的是封装数据以及跟这些数据相关的行为。比如一个字符串,通常我们不关心这些字符串是什么,关心的是我能对这些字符串做什么(如计算长度、裁剪),所以length、slice等都被设计成String类的属性和方法。所有字符串都是String类的实例,所以每个字符串不仅包含字符串数据,也包含可以应用在数据上的方法与属性。
封装使对象内部的变化对其他对象是不可见的,这也就使得对象之间的耦合变的松散,对象之间的通信是通过暴露API接口。当修改对象中某个方法的实现时,只要保证对外的API没有变化,就不会影响其他功能。
聚合
聚合也叫作组合,它是指把几个现有对象合并成一个新对象的过程。主要是解决复杂的问题时,可以把它分解成几个细小的问题,通过解决这些小问题进而达到解决复杂问题的目的,这就是聚合的用处。
比如Person都有name、skill属性,但是name可能是多个对象(如昵称、真名、乳名、小名),skill也可能是多个对象(如programme、English、drawing),此时的Person对象就是由若干子对象聚合而成的对象。
继承
继承的目的是实现代码的复用。传统OOP中,继承是是指类与类之间的关系,由于JS没有类,所以JS中的继承是对象与对象之间的关系。
以Person举例,Person有name、age、sex属性,有sleep、talk方法。当我们设计Programmer时,可以让他继承自Person对象,这样那些重复的属性和方法就不需要再实现一次了,只实现Programmer特有的属性和方法即可。
当一个对象继承自另一个对象时,通常会加入新的方法,这个过程叫做“B继承自A”或“B扩展自A”。新对象可以根据自身需要,重新定义继承而来的方法和属性,这样做并不会影响原对象,这种重定义继承方法的过程叫做覆写。
多态
多态这个词来源于希腊文polymorphism,字面意思就是复数形态,即同一个操作作用于不同的对象,产生不同的解释和执行结果。
现在有“li、wang、zhao”三个变量,li是Programmer的实例,wang是Designer的实例,zhao是ProjectManager的实例。Programmer、Designer和ProjectManager都继承自Person对象,它们都有talk方法,当我们调用li的talk方法时他谈的是代码,调用wang的talk方法时谈的是设计,代用zhao的talk方法时谈的时项目进度。像这种不同对象通过相同的方法调用来实现各自行为的能力,称之为多态。
总结
对象:Person是一个对象
属性:Person有name、age、sex属性
方法:Person有talk、sleep方法
类:Programmer、Designer和ProjectManager是Person的类
封装:Person对象对外暴露的方法和属性,外部调用时无需关心是如何实现的
聚合:Person的name属性包含小名、昵称、真名
继承:Programmer、Designer和ProjectManager都有talk、sleep方法和name、age、sex属性
多态:li是Programmer的实例,wang是Designer的实例,zhao是ProjectManager的实例。当调用li的talk方法时他谈的是代码,调用wang的talk方法时谈的是设计,代用zhao的talk方法时谈的时项目进度。