『JavaScript』封装
封装可以被定义为对对象的内部数据表现形式和实现细节进行隐藏。通过封装可以强制实施信息隐藏。
在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");
利弊
利处
- 封装保护了内部数据的完整性;
- 封装使对象的重构更轻松;
- 弱化模块间的耦合,提高对象的可重用性;
- 有助于避免命名空间冲突;
- ……
弊处
- 私用方法很难测试;
- 必须与复杂的作用域链打交道,使错误调度更困难;
- 容易形成过度封装;
- JavaScript并不原生支持封装,所以在JavaScript中实现封装存在复杂性的问题;
- ……
『JavaScript』封装的更多相关文章
- [原创] 【2014.12.02更新网盘链接】基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装
[原创] [2014.12.02更新网盘链接]基于EasySysprep4.1的 Windows 7 x86/x64 『视频』封装 joinlidong 发表于 2014-11-29 14:25:50 ...
- 『JavaScript』核心
弱类型语言 JavaScript是一种弱类型的语言.变量可以根据所赋的值改变类型.原始类型之间也可以进行类型转换.其弱类型的物质为其带来了极大的灵活性. 注意:原始类型使用值传递,复合类型使用引用传递 ...
- 『JavaScript』new关键字
原文 new关键字做了什么 在JavaScript中,使用new关键字后,意味着做了如下四件事情: 创建一个新的对象,这个对象的类型是object: 设置这个新的对象的内部.可访问性和[[protot ...
- 『JavaScript』模仿接口
JavaScript中并没有内置的创建或实现接口的方法.这里将利用JavaScript的灵活性,来实现与接口意义相同的功能. 什么是接口? 接口的好处: 接口提供了一种用以说明一个对象应该具有哪些方法 ...
- 转:『代码』JS封装 Ajax级联下拉列表
在博客园看到一篇不错的AJAX级联下拉列表,觉得不错,特地拿下来 :转载来自:『大雪无痕』 ,原文地址 //当一个 下拉列表 改变时,触发所有联动:(警告:各下拉列表之间 请不要出现 循环依赖) // ...
- 『TensorFlow』专题汇总
TensorFlow:官方文档 TensorFlow:项目地址 本篇列出文章对于全零新手不太合适,可以尝试TensorFlow入门系列博客,搭配其他资料进行学习. Keras使用tf.Session训 ...
- 『TensorFlow』批处理类
『教程』Batch Normalization 层介绍 基础知识 下面有莫凡的对于批处理的解释: fc_mean,fc_var = tf.nn.moments( Wx_plus_b, axes=[0] ...
- 『TensorFlow』读书笔记_VGGNet
VGGNet网络介绍 VGG系列结构图, 『cs231n』卷积神经网络工程实践技巧_下 1,全部使用3*3的卷积核和2*2的池化核,通过不断加深网络结构来提升性能. 所有卷积层都是同样大小的filte ...
- 『TensorFlow』命令行参数解析
argparse很强大,但是我们未必需要使用这么繁杂的东西,TensorFlow自己封装了一个简化版本的解析方式,实际上是对argparse的封装 脚本化调用tensorflow的标准范式: impo ...
随机推荐
- Matlab Colour Theme
[转]http://blog.csdn.net/df865017/article/details/48164429 使用MATLAB进行编码时, 长时间面对白底黑字的屏幕, 眼睛会疼! 因此, 选择一 ...
- React简介
React JS:可以用react的语法,来编写网页的交互效果 React Native:可以让我们借用react的语法来编写原生的app应用 React VR:在react的基础上去开发VR,或者说 ...
- 更改win7关机菜单选项功能
说明:如果你不希望别人对你的电脑进行注销切换等操,那么可以使用如下的方法 实现效果: 实现步骤: 效果1 1>切换用户: 2>注销:(需重启资源管理器生效) 效果2:
- 广义线性模型(GLM, Generalized Linear Model)
引言:通过高斯模型得到最小二乘法(线性回归),即: 通过伯努利模型得到逻辑回归,即: 这些模型都可以通过广义线性模型得到.广义线性模型是把自变量的线性预测函数当作因变量的估计值.在 ...
- python+appuim 处理系统权限弹窗
from appium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.w ...
- git上传过滤忽略文件
有些时候我们不想把某些文件纳入版本控制中,比如数据库文件,临时文件,设计文件等 在主目录下建立".gitignore"文件,此文件有如下规则: 忽略文件中的空行或以井号(#)开始的 ...
- Android学习笔记_76_Android ProgressBar 进度条
android 进度条的样式 例1:(默认样式(中等圆形))Xml代码 <ProgressBar android:id="@+id/progressBar1" ...
- 【办公-Word-VB】人民币大写转换-带完整注释
完整代码见:我的CSDN博客 -------------------- 应公司财务人员的请求,需在Word中做个:输入阿拉伯数字,自动转换成大写,并填充到Word控件中对应的亿.万.千控件格子的功能, ...
- Sublime Text Build 3065 License key
Sublime Text Build 3065 License key 复制如下三个任意一个正版注册码即可 —– BEGIN LICENSE —– Andrew Weber Single User ...
- 字段中有空的时候 进行逻辑运算,mysql 与 oracle 处理函数IFNULL() 与 nvl() ,选取NULL 值 。
mySQL数据库: SELECT id_p,IFNULL(math,0)+IFNULL(english,0) 总分 from mytest_brian1 Oracle 数据库: select id_ ...