前面的话

  面向对象描述了一种代码的组织结构形式——一种在软件中对真实世界中问题领域的建模方法。本文将从理论层面,介绍javascript面向对象程序程序(OOP)中一些常见的概念

对象

  所谓对象,本质上就是指事物(包括人和物)在程序设计语言中的表现形式。这里的事物可以是任何东西(如某个客观存在的对象,或者某些较为抽象的概念)。例如,对于猫这种常见对象来说,具有某些明确的特征(如颜色、名字、体型等),能执行某些动作(如喵喵叫、睡觉、躲起来、逃跑等)。在OOP语义中,这些对象特征都叫做属性,而那些动作则被称为方法

  此外,还有一个口语方面的类比:对象往往是用名词表示的(如book、person),方法一般都是些动词(如read、run),属性值则往往是一些形容词

  1. The black cat sleeps on my head

  cat是一个对象,black是一个颜色属性值,sleep代表一个动作,也就是OOP语义中的方法。on my head是动作sleep的限定条件。因此它可以当做传递给sleep方法的一个参数

  在现实生活中,相似对象之间往往都有一些共同的组成特征。例如蜂鸟和老鹰都具有鸟类的特征,因此它们可以被统称为鸟类。在OOP中,类实际上就是对象的设计蓝图或制作配方。对象这个词,有时候也叫做实例。所以,老鹰是鸟类的一个实例。可以基于同一个类创建出许多不同的对象,因为类更多的是一种模板。而对象则是在这些模板的基础上被创建出来的实体

  javascript实际上压根没有类。该语言的一切都是基于对象的,其依靠的是一套原型(prototype)系统。而原型本身实际上也是一种对象

  在传统的面向对象语言中,基于Person类创建了一个Match的新对象,而在javascript中,则是将现有的Person对象扩展成一个Match的新对象

封装

  封装主要用于阐述对象中所包含的内容。封装概念通常由两部分组成:相关的数据(用于存储属性)、基于这些数据所能做的事(所能调用的方法)

  封装的目的是将信息隐藏,即方法与属性的可见性。一般而言,封装包括封装数据和封装实现

  在许多语言的对象系统中,封装数据是由语法解析来实现的,这些语言提供了public、private、protected这些关键字来限定方法和属性的可见性,这种限定分类定义了对象用户所能访问的层次

  但javascript并没有提供对这些关键字的支持,只能依赖变量的作用域来实现封装特性, 而且只能模拟出 public 和 private 这两种封装性。除了ECMAScript6中提供的let之外,一般通过函数来创建作用域:

  1. var myObject = (function(){
  2. var name = 'match'; // 私有(private)变量
  3. return {
  4. getName: function(){ // 公开(public)方法
  5. return name;
  6. }
  7. }
  8. })();
  9. console.log( myObject.getName() );// 输出:match
  10. console.log( myObject.name ) // 输出:undefined

  面向对象编程强调的是数据和操作数据的行为本质上是互相关联的,因此好的设计就是把数据以及和它相关的行为封装起来。举例来说,用来表示一个单词或者短语的一串字符通常被称为字符串。字符就是数据。但是关心的往往不是数据是什么,而是可以对数据做什么,所以可以应用在这种数据上的行为(计算长度、添加数据、搜索等等)都被设计成 String 类的方法。所有字符串都是 String 类的一个实例,也就是说它是一个包裹,包含字符数据和可以应用在数据上的函数

  封装不仅仅是隐藏数据,还包括隐藏实现细节、设计细节以及隐藏对象的类型等

  从封装实现细节来讲,封装使得对象内部的变化对其他对象而言是透明的,也就是不可见的。 对象对它自己的行为负责。其他对象或者用户都不关心它的内部实现。封装使得对象之间的耦合变松散,对象之间只通过暴露的 API 接口来通信。当修改一个对象时,可以随意地修改它的内部实现,只要对外的接口没有变化,就不会影响到程序的其他功能

聚合

  所谓聚合,有时候也叫做组合,实际上是指将几个现有对象合并成一个新对象的过程。总之,这个概念强调的是将多个对象合而为一的能力。通过聚合这种强有力的方法,可以将一个问题分解成多个更小的问题。这样一来,问题就会显得更易于管理(便于各个击破)。当一个问题域的太过复杂时,就可以考虑将它分解成若干个子问题区,并且必要的话,这些问题区还可以再继续分解成更小的分区。这样做有利于从几个不同的抽象层次来考虑这个问题

  类似的情况如Book是由一个或多个author对象,publisher对象、若干chapter对象以及一组table对象等组合而成的对象

继承

  通过继承这种方法,可以非常优雅地实现对现有代码的重用。在传统的OOP环境中,继承通常指的是类与类之间的关系,但由于javascript中不存在类,因此它的继承只能发生在对象之间

  比如,有一个Person的一般性对象,其中包含一些姓名、性别之类的属性,以及一些功能性函数,如步行、谈话、睡觉、吃饭等。然后,需要一个Programmer对象时,可以让Programmer继承自Person,Programmer对象只需要实现属于它自己的那部分特殊功能(如编写代码),而其余部分重用Person的实现即可

  当一个对象继承自另一个对象时,通常会往其中加入新的方法,以扩展被继承的老对象。通常将这一过程称之为“B继承自A”或“B扩展自A”。另外对于新对象来说,它可以根据自己的需要,从继承的那组方法中选择几个来重新定义。这样做并不会改变对象的接口,因为其方法名是相同的,只不过当调用新对象时,该方法的行为与之前不同了。这种重定义继承方法的过程叫做覆写

多态

  多态一词源于希腊文polymorphism,拆开来看是poly(复数)+morph(形态)+ism,从字面意思可以理解为复数形态

  多态的实际含义是:同一个操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。换句话说,给不同的对象发送同一个消息的时候,这些对象会根据这个信息分别给出不同的反馈

  Programmer对象继承了上一级对象Person的所有方法。这意味着这两个对象都实现了"talk"等方法。现在,代码中有一个叫做“Match”的变量,即使是在不知道它是一个Person对象还是一个Programmer对象的情况下,也依然可以直接调用该对象的"talk"方法,而不必担心这会影响代码的正常工作。类似这种不同对象通过相同的方法调用来实现各自行为的能力,称之为多态

  多态背后的思想是将“做什么”和“谁去做以及怎样去做”分离开来,也就是将“不变的事物”与“可能改变的事物”分离开来。把不变的部分隔离出来,把可变的部分封装起来,这给予了我们扩展程序的能力,程序看起来是可生长的,也符合开放——封闭原则,相对于修改代码来说,仅仅增加代码就能完成同样的功能,这显然优雅和安全得多

  多态最根本的作用是通过把过程化的条件分支语句转化为对象的多态性,从而消除这些条件分支语句

总结

  下面来对上面提到的概念进行总结

  对象:Match是一个男人(后者是一个对象)

  属性:Match是男性,黄皮肤,黑头发

  方法:Match能吃饭、睡觉、喝水、做梦

  类:Match是Programmer类的一个实例

  原型对象:Match是一个由Programmer对象扩展而来的新对象

  封装:Match对象包含了数据和基于这些数据的方法

  聚合:Match只是整个Web开发团队对象的一部分,该团队还包括一个Designer对象Wang,以及一个ProjectManager对象Li

  继承:Designer、ProjectManager、Programmer都是分别扩展自Person对象的新对象

  多态:可以随时调用Match、Wang、Li这三个对象各自的talk方法,它们都可以正常工作,尽管这些方法会产生不同的结果。如Match可能谈得更多的是代码的性能,Wang更倾向于谈代码的优雅性,而Li强调的是最后期限。总之,每个对象都可以重新自定义它们的继承方法talk

javascript面向对象系列第四篇——OOP中的常见概念的更多相关文章

  1. javascript面向对象系列第四篇——选项卡的实现

    前面的话 面向对象的应用并非只是读几本书那么容易,需要有大量的工程实践做基础才能真正理解并学会使用它.本文将用面向对象的技术来制作一个简单的选项卡 图示说明 由图示结果看到,这是一个非常简单的选项卡. ...

  2. javascript面向对象系列第三篇——实现继承的3种形式

    × 目录 [1]原型继承 [2]伪类继承 [3]组合继承 前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.本文是javascript面向对象系列第三篇——实现继承的3种形式 [ ...

  3. 深入理解javascript作用域系列第四篇——块作用域

    × 目录 [1]let [2]const [3]try 前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用 ...

  4. 深入理解javascript作用域系列第四篇

    前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的 ...

  5. javascript运动系列第四篇——抖动

    × 目录 [1]原理介绍 [2]代码实现 [3]实例应用 前面的话 在运动系列中,前面分别介绍了匀速运动.变速运动和曲线运动.下面介绍一种特殊的运动形式——抖动 原理介绍 抖动其实是往复运动的一种特殊 ...

  6. 前端学PHP之面向对象系列第四篇——关键字

    × 目录 [1]public [2]protected [3]private[4]final[5]static[6]const[7]this[8]self[9]parent 前面的话 php实现面向对 ...

  7. 深入理解javascript函数系列第四篇——ES6函数扩展

    × 目录 [1]参数默认值 [2]rest参数 [3]扩展运算符[4]箭头函数 前面的话 ES6标准关于函数扩展部分,主要涉及以下四个方面:参数默认值.rest参数.扩展运算符和箭头函数 参数默认值 ...

  8. javascript面向对象系列第五篇——拖拽的实现

    前面的话 在之前的博客中,拖拽的实现使用了面向过程的写法.本文将以面向对象的写法来实现拖拽 写法 <style> .test{height: 50px;width: 50px;backgr ...

  9. 前端学PHP之面向对象系列第四篇-----关键字

    public public表示公有,它具有最大的访问权限,被定义为公有的类成员可以在任何地方被访问 如果属性用 var 定义,则被视为公有,如果方法没有设置关键字,则该方法默认为公有 <?php ...

随机推荐

  1. JavaScrpit中异步请求Ajax实现

    在前端页面开发的过程中,经常使用到Ajax请求,异步提交表单数据,或者异步刷新页面. 一般来说,使用Jquery中的$.ajax,$.post,$.getJSON,非常方便,但是有的时候,我们只因为需 ...

  2. Visual paradigm软件介绍

    Visual paradigm软件介绍 说起Visual Paradigm你可能并不陌生,因为此前有一款功能强大的UML软件叫Visual Paradigm for UML,在这款软件在v11.1的时 ...

  3. Connect the Cities(prim)用prim都可能超时,交了20几发卡时过的

    Connect the Cities Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

  4. sersync实现数据实时同步

    1.1 第一个里程碑:安装sersync软件 1.1.1 将软件上传到服务器当中并解压 1.上传软件到服务器上 rz -E 为了便于管理上传位置统一设置为 /server/tools 中 2.解压软件 ...

  5. mouseover事件mouseenter事件

    1. mouseover:会在鼠标进入该元素或者该元素的子元素时触发 mouseenter:只在鼠标进入该元素时触发 mouseout:在鼠标移出该元素或则该元素的子元素时触发 mouseleave: ...

  6. day2--命令总结

    1.mkdir               创建目录  -p递归(用来创建层级目录,底层目录不存在) 2.touch               创建文件 3.ls                  ...

  7. 机器学习之Logistic 回归算法

    1 Logistic 回归算法的原理 1.1 需要的数学基础 我在看机器学习实战时对其中的代码非常费解,说好的利用偏导数求最值怎么代码中没有体现啊,就一个简单的式子:θ= θ - α Σ [( hθ( ...

  8. JS中encodeURI,escape,encodeURIComponent区别

    js对文字进行编码涉及3个函数:escape,encodeURI,encodeURIComponent,相应3个解码函数:unescape,decodeURI,decodeURIComponent 1 ...

  9. stm32l053r8 nucelo板的串口实验

    stm32cubel0的HAL驱动实例中,基于stm32l53R8  nucelo板的官方串口通讯例程,是使用USART1实现在两块stm32l053r8 nucelo板间通讯.而在实际中,笔者手中只 ...

  10. C#写的较完美验证码通用类

    using System; using System.Collections; using System.ComponentModel; using System.Data; using System ...