javascript使用闭包模拟对象的私有属性和方法


Posted in Javascript onOctober 05, 2016

最近因为做了一个项目,其中涉及到了js私有方法,这个概念在其语言里面是很常见的,很多语言都有private这个关键字,只要在一个类的前面加上private就表示申明了一个私有方法,但是javascript在面向对象的方面没有那么多的特征,他没有专门的private关键字,。要做到这一点就必须使用js自己的一些特性来变相的完成。

首先javascript里面有一个高级特性叫闭包,简单的说js的闭包可以理解成是一种现象或者特性,一般出现在两个函数嵌套的情况下,看例子:

function a(){
var eg = 1;
return function(){
alert(eg);
}
}
var c = a();

a函数里返回了一个函数,返回的函数被全局作用域下的c接受了,此时因为返回的函数调用了a函数里面的eg变量,并且被全局作用域下的变量c引用,此时下形成闭包,a函数的内存空间不会被收回,这个闭包的理解其实和js的垃圾回收机制有关,js的垃圾回收其实是靠引用来计算的,比如我们申明了一个函数,这个函数就会有一个引用指向他自己,当函数运行结束的时候销毁引用,js如果发现没有引用的函数就会销毁这个函数的内存空间,函数也就没有了。我们上面的例子中首先a函数运行,给eg赋值1,然后返回一个匿名函数,到此a函数运行完了,按照原有的理论,此时a函数应该被销毁,但是此时他返回了一个函数,这个函数被全局下的变量c引用,c是不会被销毁的,除非我们手动销毁,而且这个返回的函数引用了a函数的变量eg,js引擎会认为eg依然是有用的,因为他仍然在被使用,因此包含eg这个局部变量的函数a也不会被销毁。

闭包的理解可能不是一下讲的通的,这里其实还涉及到一个作用域的问题,我记得以前有人说返回的这个函数被c接收了,c是在全局作用下的,为什么调用c的时候会弹出a函数里面的eg,难道不应该是全局作用域下的eg吗?而且js的函数作用于是局部的,外部不能访问。其实这里有一个理论,记住就可以,js里的函数作用域取决于函数定义的位置,而不是函数调用的位置,也就是说,函数在什么地方定义的,他的作用域就决定了,不管他在什么地方调用,作用域都不会改变,返回的这个匿名函数是在a函数里面定义的,所以他的上级作用域就是这个a函数,而不是全局作用域。

这里要说的私有方法其实和闭包是有关系的,私有方法在其他语言里面是不被访问到的,除非有专门的接口,js的局部作用域里面的东西在正常情况下也是不能被外部访问到,但是上面例子显示了,通过闭包的方式可以访问到,这样我们就可以利用这个特性,看例子:

var book = (function(){
var page = 100;
return function(){
this.auther = 'dava';
this.price = 200;
this._page = function(){
alert(page);
}
}
})();

var a = new book();
a.auther//"dava"
a.price//  200
a.page//"wrong"
a._page()//  100

这里例子用了一个函数自动执行,一上来就执行了一个匿名函数,并且在匿名函数里面定义了一个局部变量page,然后又返回了一个匿名函数,并且被全局作用域下的book变量接收,此时使用new 调用book就会生成一个新对象a。其中auther属性和price属性可以直接通过对象访问,因为这些属性都是new的时候直接定义在返回的对象身上的,而page属性则没有,因此不能反回,但此时如果我想访问page属性,那就得依靠闭包了,返回的函数在外层的匿名函数里面,因此在返回的函数身上定义了一个方法叫_page,这个方法弹出了page属性,按照js作用域的关系,当前作用域找不到page,就会到上层作用域去寻找,这样就找到了。通过这种方式我们就把私有方法和公有方法区分开了。

Javascript 相关文章推荐
javascript 对象定义方法 简单易学
Mar 22 Javascript
基于jQuery实现模拟页面加载进度条
Apr 01 Javascript
fmt:formatDate的输出格式详解
Jan 09 Javascript
Javascript监视变量变化的方法
Jun 09 Javascript
javascript常用的方法整理
Aug 20 Javascript
jQuery实现放大镜效果实例代码
Mar 17 Javascript
浅析C/C++,Java,PHP,JavaScript,Json数组、对象赋值时最后一个元素后面是否可以带逗号
Mar 22 Javascript
jquery判断iPhone、Android设备类型
Sep 14 Javascript
微信小程序  wx.request合法域名配置详解
Nov 23 Javascript
利用iscroll4实现轮播图效果实例代码
Jan 11 Javascript
Node.js与Sails redis组件的使用教程
Feb 14 Javascript
AngularJS页面带参跳转及参数解析操作示例
Jun 28 Javascript
Node.js与MySQL交互操作及其注意事项
Oct 05 #Javascript
JavaScript定义数组的三种方法(new Array(),new Array('x','y')
Oct 04 #Javascript
js当前页面登录注册框,固定div,底层阴影的实例代码
Oct 04 #Javascript
总结Javascript中数组各种去重的方法
Oct 04 #Javascript
Javascript中arguments对象的详解与使用方法
Oct 04 #Javascript
js判断浏览器是否支持严格模式的方法
Oct 04 #Javascript
浅谈jquery高级方法描述与应用
Oct 04 #Javascript
You might like
php park、unpark、ord 函数使用方法(二进制流接口应用实例)
2010/10/19 PHP
php HandlerSocket的使用
2011/05/02 PHP
PHP二维数组的去重问题解析
2011/07/17 PHP
通过PHP current函数获取未知字符键名数组第一个元素的值
2013/06/24 PHP
ThinkPHP快速入门实例教程之数据分页
2014/07/01 PHP
Yii2汉字转拼音类的实例代码
2017/04/18 PHP
微信接口生成带参数的二维码
2017/07/31 PHP
Yii框架ACF(accessController)简单权限控制操作示例
2019/04/26 PHP
基于jquery的loading 加载提示效果实现代码
2011/09/01 Javascript
js仿苹果iwatch外观的计时器代码分享
2015/08/26 Javascript
11种ASP连接数据库的方法
2015/09/18 Javascript
JavaScript必知必会(三) String .的方法来自何方
2016/06/08 Javascript
你不需要jQuery(三) 新AJAX方法fetch()
2016/06/14 Javascript
微信小程序 require机制详解及实例代码
2016/12/14 Javascript
bootstrap 模态框(modal)实现水平垂直居中显示
2017/01/23 Javascript
Angular 4依赖注入学习教程之ValueProvider的使用(七)
2017/06/04 Javascript
解决Vue2.0 watch对象属性变化监听不到的问题
2018/09/11 Javascript
Python压缩和解压缩zip文件
2015/02/14 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
2017/12/14 Python
对python numpy数组中冒号的使用方法详解
2018/04/17 Python
Python中list的交、并、差集获取方法示例
2019/08/01 Python
pytorch使用指定GPU训练的实例
2019/08/19 Python
Python笔记之代理模式
2019/11/20 Python
python NumPy ndarray二维数组 按照行列求平均实例
2019/11/26 Python
在pycharm中创建django项目的示例代码
2020/05/28 Python
Python进行统计建模
2020/08/10 Python
SIMON MILLER官网:洛杉矶的生活方式品牌
2020/10/19 全球购物
有关打架的检讨书
2014/01/25 职场文书
班主任经验交流会主持词
2014/04/01 职场文书
小班上学期评语
2014/05/05 职场文书
老兵退伍标语
2014/10/07 职场文书
战略性融资合作协议书范本
2014/10/17 职场文书
出差报告范文
2014/11/06 职场文书
羊脂球读书笔记
2015/06/30 职场文书
SQL Server基本使用和简单的CRUD操作
2021/04/05 SQL Server
python自动化八大定位元素讲解
2021/07/09 Python