理解javascript封装


Posted in Javascript onFebruary 23, 2016

封装可以被定义为对对象的内部数据表现形式和实现细节进行隐藏。通过封装可以强制实施信息隐藏。

在JavaScript中,并没有显示的声明私有成员的关键字等。所以要想实现封装/信息隐藏就需要从另外的思路出发。我们可以使用闭包的概念来创建只允许从对象内部访问的方法和属性,来达到封装的要求。

基本方式
一般来说,我们学用的有三种方法来达到封装的目的。

使用this.XXX来声明一个变量,然后再声明getXXX、setXXX等取值、赋值的方法。
使用this._XXX来声明一个变量,然后再声明getXXX、setXXX等取值、赋值的方法。
利用“函数作用域”这一个概念来做。
1. 门户大开型

var Book = function(isbn,title,author){
 this.setIsbn(isbn);
 this.setTitle(title);
 this.setAuthor(author);
};

Book.prototype = {
 setIsbn: function(isbn){
  this.isbn = isbn;
 },
 getIsbn: function(){
  return this.isbn;
 },
 setTitle: function(title){
  this.title = title;
 },
 getTitle: function(){
  return this.title;
 },
 setAuthor: function(author){
  this.author = author;
 },
 getAuthor: function(){
  return this.author;
 }
};

使用这种方法实现的封装,虽然实现了取值器与赋值器以保护私有属性。但是在实际使用中,私有属性依然可以从外部访问,所以从根本上讲,没有实现封装。

2. 用命名规范进行区别

var Book = function(isbn,title,author){
 this.setIsbn(isbn);
 this.setTitle(title);
 this.setAuthor(author);
};

Book.prototype = {
 setIsbn: function(isbn){
  this._isbn = isbn;
 },
 getIsbn: function(){
  return this._isbn;
 },
 setTitle: function(title){
  this._title = title;
 },
 getTitle: function(){
  return this._title;
 },
 setAuthor: function(author){
  this._author = author;
 },
 getAuthor: function(){
  return this._author;
 }
};

使用这种方法与第一种类似,区别在于使用不同的命名来保护私有属性的使用。但是,从实际应用来说其仍然没有实现封装。

3. 使用函数作用域

var Book = function(newIsbn,newTitle,newAuthor){
 var isbn,title,author;

 this.setIsbn=function(newIsbn){
  isbn = newIsbn;
 };
 this.getIsbn=function(){
  return isbn;
 };
 this.setTitle=function(newTitle){
  title = newTitle;
 };
 this.getTitle=function(){
  return title;
 };
 this.setIsbn=function(newAuthor){
  author = newAuthor;
 };
 this.getIsbn=function(){
  return author;
 };
}

由于在JavaScript的函数中声明的变量是有作用域的,所以使用这种方法可以避免在外部直接访问私有属性。基本达到封装所要求的内容。

这里要注意的是,我们在函数的内部,可以使用this.XXX以及var来声明变量。区别是使用this.XXX声明的变量在外部是可以访问的。使用var声明的变量,由于受到函数作用域的保护,在函数的外部是无法直接访问的。

4. 使用函数作用域的变形

var Book = (function(){
 // ...其他静态方法

 return function(newIsbn,newTitle,newAuthor){
  var isbn,title,author;

  this.setIsbn=function(newIsbn){
   isbn = newIsbn;
  };
  this.getIsbn=function(){
   return isbn;
  };
  this.setTitle=function(newTitle){
   title = newTitle;
  };
  this.getTitle=function(){
   return title;
  };
  this.setIsbn=function(newAuthor){
   author = newAuthor;
  };
  this.getIsbn=function(){
   return author;
  };
 };
})();

这种方法是直接返回一个构造器的执行。且这里的构造器是一个内嵌函数。

这种方法的优点是“在内存中只会存在一份。因为其他静态方法被声明在构造器之外,所以它们不是特权方法。”

判断一个方法是否应该被设计为静态方法的原则是“这个方法是否会访问私有属性”。如果它不需要,那么将其设计为静态方法会更有效率,因为它只会被创建一份。

常量
我们可以使用“只有取值器,没有赋值器”的方式来实现常量。

// 1.
var Book = function(){
 var constants = ["key1": "1","key2": "2","key3": "3"];

 this.getConstant = function(key){
  return constants[key];
 };
};

Book.getConstant("key1");

// 2.
var Book = (function(){
 var constants = ["key1": "1","key2": "2","key3": "3"];

 var con = function(){};
 con.getConstant = function(name){
  return constants[name];
 };

 return con;
})();

Book.getConstant("key1");

利弊
1、利处

封装保护了内部数据的完整性;
封装使对象的重构更轻松;
弱化模块间的耦合,提高对象的可重用性;
有助于避免命名空间冲突;
……
2、弊处

私用方法很难测试;
必须与复杂的作用域链打交道,使错误调度更困难;
容易形成过度封装;
JavaScript并不原生支持封装,所以在JavaScript中实现封装存在复杂性的问题;

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
JS控制图片等比例缩放的示例代码
Dec 24 Javascript
JS的get和set使用示例
Feb 20 Javascript
node.js应用后台守护进程管理器Forever安装和使用实例
Jun 01 Javascript
Ext修改GridPanel数据和字体颜色、css属性等
Jun 13 Javascript
JavaScript动态改变HTML页面元素例如添加或删除
Aug 10 Javascript
jQuery基础知识点总结(必看)
May 31 Javascript
Angular实现的日程表功能【可添加及隐藏显示内容】
Dec 27 Javascript
webpack项目轻松混用css module的方法
Jun 12 Javascript
浅析JS中什么是自定义react数据验证组件
Oct 19 Javascript
基于Proxy的小程序状态管理实现
Jun 14 Javascript
vue实现全匹配搜索列表内容
Sep 26 Javascript
javascript实现超好看的3D烟花特效
Jan 01 Javascript
学习Javascript面向对象编程之封装
Feb 23 #Javascript
javascript每日必学之封装
Feb 23 #Javascript
jQuery常用知识点总结以及平时封装常用函数
Feb 23 #Javascript
使用Javascript实现选择下拉菜单互移并排序
Feb 23 #Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
Feb 23 #Javascript
JavaScript tab选项卡插件实例代码
Feb 23 #Javascript
Javascript技术栈中的四种依赖注入详解
Feb 23 #Javascript
You might like
php+mysql事务rollback&commit示例
2010/02/08 PHP
让php处理图片变得简单 基于gb库的图片处理类附实例代码下载
2011/05/17 PHP
php实现的替换敏感字符串类实例
2014/09/22 PHP
php实现36进制与10进制转换功能示例
2017/01/10 PHP
php + nginx项目中的权限详解
2017/05/23 PHP
javascript 获取图片颜色
2009/04/05 Javascript
5款Javascript颜色选择器
2009/10/25 Javascript
淘宝搜索框效果实现分析
2011/03/05 Javascript
向当前style sheet中插入一个新的style实现方法
2013/04/01 Javascript
客户端js判断文件类型和文件大小即限制上传大小
2013/11/20 Javascript
IE下支持文本框和密码框placeholder效果的JQuery插件分享
2015/01/31 Javascript
JS+CSS实现TreeMenu二级树形菜单完整实例
2015/09/18 Javascript
AngularJs用户登录问题处理(交互及验证、阻止FQ处理)
2017/10/26 Javascript
webpack项目轻松混用css module的方法
2018/06/12 Javascript
浅谈vue引用静态资源需要注意的事项
2018/09/28 Javascript
浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
2018/12/20 Javascript
详解webpack4.x之搭建前端开发环境
2019/03/28 Javascript
vue elementUI table 自定义表头和行合并的实例代码
2019/05/22 Javascript
vue vantUI实现文件(图片、文档、视频、音频)上传(多文件)
2019/10/15 Javascript
node.js中module模块的功能理解与用法实例分析
2020/02/14 Javascript
Python实现制度转换(货币,温度,长度)
2019/07/14 Python
pandas的排序和排名的具体使用
2019/07/31 Python
Python imread、newaxis用法详解
2019/11/04 Python
Python datetime 如何处理时区信息
2020/09/02 Python
python实现经典排序算法的示例代码
2021/02/07 Python
纯CSS3代码实现switch滑动开关按钮效果
2016/08/30 HTML / CSS
全球在线商店:BerryLook
2019/04/14 全球购物
UNIX命令速查表
2012/03/10 面试题
优秀教师主要事迹
2014/02/01 职场文书
2014年公务员思想汇报范文:全心全意为人民服务
2014/03/06 职场文书
党的群众路线教育实践活动党员个人剖析材料
2014/10/08 职场文书
余世维讲座观后感
2015/06/11 职场文书
30岁前绝不能错过的10本书
2019/08/08 职场文书
关于党风廉政建设宣传教育月的活动总结!
2019/08/08 职场文书
anaconda python3.8安装后降级
2021/06/11 Python
python中super()函数的理解与基本使用
2021/08/30 Python