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 相关文章推荐
日期函数扩展类Ver0.1.1
Sep 07 Javascript
ExtJS GTGrid 简单用户管理
Jul 01 Javascript
检测jQuery.js是否已加载的判断代码
May 20 Javascript
javascript实现倒计时并弹窗提示特效
Jun 05 Javascript
JS获取鼠标选中的文字
Aug 10 Javascript
JavaScript使用delete删除数组元素用法示例【数组长度不变】
Jan 17 Javascript
Vue如何实现组件的源码解析
Jun 08 Javascript
vue-cli结合Element-ui基于cropper.js封装vue实现图片裁剪组件功能
Mar 01 Javascript
如何手写简易的 Vue Router
Oct 10 Javascript
浅析VUE防抖与节流
Nov 24 Vue.js
详解vue-cli项目在IE浏览器打开报错解决方法
Dec 10 Vue.js
Vue中引入svg图标的两种方式
Jan 14 Vue.js
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
Yii学习总结之安装配置
2015/02/22 PHP
PHP jpgraph库的配置及生成统计图表:折线图、柱状图、饼状图
2017/05/15 PHP
php实现数组纵向转横向并过滤重复值的方法分析
2017/05/29 PHP
php报错502badgateway解决方法
2019/10/11 PHP
如何在PHP中生成随机数
2020/06/04 PHP
用XMLDOM和ADODB.Stream实现base64编码解码实现代码
2010/11/28 Javascript
映彩衣的js随笔(js图片切换效果)
2011/07/31 Javascript
Jquery ajax传递复杂参数给WebService的实现代码
2011/08/08 Javascript
JavaScript伸缩的菜单简单示例
2013/12/03 Javascript
JQuery调用WebServices的方法和4个实例
2014/05/06 Javascript
在JavaScript中正确引用bind方法的应用
2015/05/11 Javascript
深入理解Vue-cli搭建项目后的目录结构探秘
2017/07/13 Javascript
JavaScript之创意时钟项目(实例讲解)
2017/10/23 Javascript
el-input 标签中密码的显示和隐藏功能的实例代码
2019/07/19 Javascript
vue 导航内容设置选中状态样式的例子
2019/11/01 Javascript
微信小程序中的video视频实现 自定义播放按钮、封面图、视频封面上文案
2020/01/02 Javascript
压缩Vue.js打包后的体积方法总结(Vue.js打包后体积过大问题)
2020/02/03 Javascript
使用node.JS中的url模块解析URL信息
2020/02/06 Javascript
Node.js API详解之 repl模块用法实例分析
2020/05/25 Javascript
[01:02:53]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第二局
2016/03/06 DOTA
python3.x实现发送邮件功能
2018/05/22 Python
Python实现常见的回文字符串算法
2018/11/14 Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
2019/02/16 Python
Python语言检测模块langid和langdetect的使用实例
2019/02/19 Python
python开发实例之python使用Websocket库开发简单聊天工具实例详解(python+Websocket+JS)
2020/03/18 Python
Python 排序最长英文单词链(列表中前一个单词末字母是下一个单词的首字母)
2020/12/14 Python
美国眼镜网站:EyeBuyDirect
2017/04/13 全球购物
法学专业个人求职信
2013/09/26 职场文书
商务英语毕业生自荐信范文
2013/11/08 职场文书
教师求职推荐信范文
2013/11/20 职场文书
求职信范文英文版
2014/01/05 职场文书
2014年学生会干事工作总结
2014/11/07 职场文书
2014年学校工作总结
2014/11/20 职场文书
综合素质评价个性与发展自我评价
2015/03/06 职场文书
文艺节目主持词
2015/07/06 职场文书
古诗之爱国古诗5首
2019/09/20 职场文书