面向对象的JavaScript --- 封装


封装

封装的目的是将信息隐藏。一般而言,我们讨论的封装是封装数据和封装实现。真正的封装为更广义的封装,不仅包括封装数据和封装实现,还包括封装类型和封装变化。

  • 封装数据
  • 封装实现
  • 封装类型
  • 封装变化

封装数据

在许多语言的对象系统中,封装数据是由语法解析来实现的,这些语言也许提供了 private、public、protected 等关键字来提供不同的访问权限。但JavaScript并没有提供对这些关键字的支持,我们只能依赖变量的作用域来实现封装特性,而且只能模拟出 public 和 private 这两种封装性。

除了 ECMAScript 6 中提供的 let 之外,一般我们通过函数来创建作用域:

var myObject = (fucntion(){
var __name = 'sven'; // 私有(private变量)
return {
getname: funvtion (){ // 公开(public)方法
return __name;
}
}
})(); console.log(myObject.getName()); // 输出: sven
console.log(myObject.__name); // 输出 undefined

外值得一提的是,在 ECAMScript 6 中,还可以通过 Symbol 创建私有属性。

封装实现

封装的目的是将信息隐藏,封装应该被视为“任何形式的封装”,也就是说,封装不仅仅是隐藏数据,还包括隐藏实现细节、设计细节以及隐藏对象的类型等。

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

封装实现细节的例子非常之多。拿迭代器来说明,迭代器的作用是在不暴露一个聚合对象的内部表示的前提下,提供一种方式来顺序访问这个聚合对象。我们编写了一个each函数,它的作用就是遍历一个聚合对象,使用这个 each 函数的人不用关心它的内部是怎样实现的,只要它提供的功能正确便可以。即使each函数修改了内部源代码,只要对外的接口或者调用方式没有变化,用户就不用关心它内部实现的改变。

封装类型

封装类型是静态类型语言中一种重要的封装方式。一般而言,封装类型是通过抽象类和接口来进行的。把对象的真正类型隐藏在抽象类或者接口之后,相比对象的类型,客户更关心对象的行为。在许多静态语言的设计模式中,想方设法地去隐藏对象的类型,也是促使这些模式诞生的原因之一。比如工厂方法模式、组合模式等。当然在 JavaScript 中,并没有对抽象类和接口的支持。 JavaScript本身也是一门类型模糊的语言。在封装类型方面, JavaScript 没有能力,也没有必要做得更多。对于JavaScript的设计模式实现来说,不区分类型是一种失色,也可以说是一种解脱。

封装变化

从设计模式的角度出发,封装在更重要的层面体现为封装变化。

《设计模式》一书曾提到如下文字:

  “考虑你的设计中哪些地方可能变化,这种方式与关注会导致重新设计的原因相反。它不是考虑什么时候会迫使你的设计改变,而是考虑你怎样才能够在不重新设计的情况下进行改变。这里的关键在于封装发生变化的概念,这是许多设计模式的主题。”

这段文字即是《设计模式》提到的“找到变化并封装之”。《设计模式》一书中共归纳总结了23种设计模式。从意图上区分, 这 23 种设计模式分别被划分为:

  • 创建型模式
  • 结构型模式
  • 行为型模式

创建型模式: 创建一个对象是种抽象行为,具体创建什么对象是可以变化的,创建型模式的目的是封装创建对象的变化。

结构型模式: 封装的是对象之间的组合关系。

行为型模式: 封装的是对象的行为变化。

通过封装变化的方式,把系统中稳定不变的部分和容易变化的部分隔离开来,在系统的演变过程中,我们只需要替换那些容易变化的部分,如果这些部分是已经封装好的,替换起来也相对容易。这可以最大程度地保证程序的稳定性和可扩展性。

从《设计模式》副标题“可复用面向对象软件的基础”可以知道,这本书理应教我们如何编写可复用的面向对象程序。这本书把大多数笔墨都放在如何封装变化上面,这跟编写可复用的面向对象程序是不矛盾的。当我们想办法把程序中变化的部分封装好之后,剩下的即是稳定而可复用的部分了。

面向对象的JavaScript --- 封装的更多相关文章

  1. javascript面向对象(一):封装

    本文来自阮一峰 学习Javascript,最难的地方是什么? 我觉得,Object(对象)最难.因为Javascript的Object模型很独特,和其他语言都不一样,初学者不容易掌握. 下面就是我的学 ...

  2. (一)Javascript 面向对象编程:封装

    Javascript 面向对象编程:封装 作者:阮一峰 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP ...

  3. JavaScript高级:JavaScript面向对象,JavaScript内置对象,JavaScript BOM,JavaScript封装

    知识点梳理 课堂讲义 1.JavaScript面向对象 1.1.面向对象介绍 在 Java 中我们学习过面向对象,核心思想是万物皆对象. 在 JavaScript 中同样也有面向对象.思想类似. 1. ...

  4. javaScript封装的各种写法

    在javascript的世界里,写法是个神奇的现象,真是百家齐开放啊!每次看到老外写的js组件,思想和写法都怪异,就没看到一个js结构基本相同的代码出来.今天,我就来谈谈js写法,我在开发过程中,也写 ...

  5. 摘抄--全面理解面向对象的 JavaScript

    全面理解面向对象的 JavaScript JavaScript 函数式脚本语言特性以及其看似随意的编写风格,导致长期以来人们对这一门语言的误解,即认为 JavaScript 不是一门面向对象的语言,或 ...

  6. 面向对象的JavaScript --- 多态

    面向对象的JavaScript --- 多态 多态 "多态"一词源于希腊文 polymorphism,拆开来看是poly(复数)+ morph(形态)+ism,从字面上我们可以理解 ...

  7. 第1章 面向对象的JavaScript

    针对基础知识的每一个小点,我都写了一些小例子,https://github.com/huyanluanyu1989/DesignPatterns.git,便于大家理解,如有疑问,大家可留言给我,最近工 ...

  8. 深入全面理解面向对象的 JavaScript

    深入全面理解面向对象的 JavaScript (原著: 曾 滢, 软件工程师, IBM,2013 年 4 月 17 日) JavaScript 函数式脚本语言特性以及其看似随意的编写风格,导致长期以来 ...

  9. 万字长文深度剖析面向对象的javascript

    目录 简介 什么是对象 构造函数 构造函数的特点 new命令的原理 prototype对象 Object的prototype操作 Object.getPrototypeOf Object.setPro ...

随机推荐

  1. 注册表修改 Devenv 默认启动 Visual Studio 版本

    本人机器上安装了多个版本Visual Studio.目前开发主要使用VS2015,,但每次使用运行->devenv 启动的都是 VS2013.所以不是很方便. 如果VS2013扩展包出问题要使用 ...

  2. mysql分表,批量生成数据

    一.mysql的分表策略 根据经验,Mysql表数据一般达到百万级别,查询效率会很低,容易造成表锁,甚至堆积很多连接,直接挂掉: 1,水平分割: 水平(横向)拆分:将同一个表的数据进行分块保存到不同的 ...

  3. linux的环境变量与文件查找

    1. 环境变量 1.1 变量 shell 中的变量有不同类型,可参与运算,有作用域限定 变量的作用域即变量的有效范围(比如一个函数中.一个源文件中或者全局范围),在该范围内只能有一个同名变量.一旦离开 ...

  4. 运行javac编译报错:仅当显式请求注释处理时才接受类名称“xxxxxx”

    发生原因:运行javac编译时没有加上扩展名.解决方法:加上.java扩展名重新编译即可,"xxxxxx.java".

  5. 用手机管理及维护MySQL,Oracle等数据库

    现在移动办公的情况及需求越来越多,平时MySQL,Oracle,SQLServer等数据库的管理都要通过客户端工具操作,现在有一款基于web网页的软件:TreeSoft数据库管理系统,在服务器布署一套 ...

  6. C++学习笔记: 智能指针

    c++ 智能指针学习新的 class Simple { public: Simple() { number = param; std::cout << "Simple: &quo ...

  7. RESTORE DATABASE命令还原SQLServer 2005 数据库

    --返回由备份集内包含的数据库和日志文件列表组成的结果集. --主要获得逻辑文件名 USE master RESTORE FILELISTONLY FROM DISK = 'g:\back.Bak' ...

  8. jquery each遍历判断返回false方法

    在jquery each中遍历返回false失效,解决办法,用变量解决: var num = 0; $(".box").find("input[type='text']& ...

  9. react context toggleButton demo

    //toggleButton demo: //code: //1.Appb.js: import React from 'react'; import {ThemeContext, themes} f ...

  10. php中怎么理解Closure的bind和bindTo

    bind是bindTo的静态版本,因此只说bind吧.(还不是太了解为什么要弄出两个版本) 官方文档: 复制一个闭包,绑定指定的$this对象和类作用域. 其实后半句表述很不清楚. 我的理解: 把一个 ...