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基础的动画教程,直观易懂
Jan 10 Javascript
浅谈关于JavaScript的语言特性分析
Apr 11 Javascript
JS创建自定义表格具体实现
Feb 11 Javascript
Bootstrap幻灯片轮播图支持触屏左右手势滑动的实现方法
Oct 13 Javascript
javascript滚轮控制模拟滚动条
Oct 19 Javascript
jQuery图片轮播实现并封装(一)
Dec 03 Javascript
angular 基于ng-messages的表单验证实例
May 04 Javascript
angularjs获取到My97DatePicker选中的值方法
Oct 02 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
Jan 02 Javascript
vue使用高德地图根据坐标定位点的实现代码
Aug 22 Javascript
webpack优化之代码分割与公共代码提取详解
Nov 22 Javascript
Vue管理系统前端之组件拆分封装详解
Aug 23 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 从数据库提取二进制图片的处理代码
2009/09/09 PHP
学习ExtJS accordion布局
2009/10/08 Javascript
让IE8支持DOM 2(不用框架!)
2009/12/31 Javascript
比较搞笑的js陷阱题
2010/02/07 Javascript
juqery 学习之三 选择器 子元素与表单
2010/11/25 Javascript
原生JS绑定滑轮滚动事件兼容常见浏览器
2014/06/30 Javascript
jQuery中width()方法用法实例
2014/12/24 Javascript
jQuery中toggleClass()方法用法实例
2015/01/05 Javascript
js获取滚动距离的方法
2015/05/30 Javascript
使用javascript提交form表单方法汇总
2015/06/25 Javascript
jQuery针对input的class属性写了多个值情况下的选择方法
2016/06/03 Javascript
JavaScript轮播图简单制作方法
2017/02/20 Javascript
详解Vue2.x-directive的学习笔记
2017/07/17 Javascript
代码详解JS操作剪贴板
2018/02/11 Javascript
webpack 单独打包指定JS文件的方法
2018/02/22 Javascript
JS获取url参数,JS发送json格式的POST请求方法
2018/03/29 Javascript
手淘flexible.js框架使用和源代码讲解小结
2018/10/15 Javascript
简单介绍Python中的try和finally和with方法
2015/05/05 Python
Python实现统计单词出现的个数
2015/05/28 Python
浅谈django中的认证与登录
2016/10/31 Python
python 输出上个月的月末日期实例
2018/04/11 Python
浅谈python str.format与制表符\t关于中文对齐的细节问题
2019/01/14 Python
python 计算一个字符串中所有数字的和实例
2019/06/11 Python
在python tkinter中Canvas实现进度条显示的方法
2019/06/14 Python
Python3 使用selenium插件爬取苏宁商家联系电话
2019/12/23 Python
Python和Anaconda和Pycharm安装教程图文详解
2020/02/04 Python
Python基于tkinter canvas实现图片裁剪功能
2020/11/05 Python
python3.8.3安装教程及环境配置的详细教程(64-bit)
2020/11/28 Python
python 爬取小说并下载的示例
2020/12/07 Python
HTML5实现文件断点续传的方法
2017/01/04 HTML / CSS
画展邀请函
2015/01/31 职场文书
2015小学毕业班工作总结
2015/07/21 职场文书
导游词之湖北梁子湖
2019/11/07 职场文书
创业计划书之酒吧
2019/12/02 职场文书
css3属性选择器 “~”(波浪号) “,”(逗号) “+”(加号)和 “>”(大于号)
2022/04/19 HTML / CSS
Mysql中mvcc各场景理解应用
2022/08/05 MySQL