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替换当前页面的方法
Apr 03 Javascript
JavaScript实现简单的二级导航菜单实例
Apr 15 Javascript
使用AngularJS对路由进行安全性处理的方法
Jun 18 Javascript
jquery实现点击查看更多内容控制段落文字展开折叠效果
Aug 06 Javascript
javascript实现网页背景烟花效果的方法
Aug 06 Javascript
探究JavaScript函数式编程的乐趣
Dec 14 Javascript
AngularJS ng-bind-html 指令详解及实例代码
Jul 30 Javascript
jQ处理xml文件和xml字符串的方法(详解)
Nov 22 Javascript
easyUI combobox实现联动效果
Jan 17 Javascript
Node.js连接MongoDB数据库产生的问题
Feb 08 Javascript
vue项目每30秒刷新1次接口的实现方法
Dec 04 Javascript
Vue使用mixin分发组件的可复用功能
Sep 01 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 批量删除 sql语句
2009/06/05 PHP
解决微信授权回调页面域名只能设置一个的问题
2016/12/11 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
2017/08/30 PHP
利用Homestead快速运行一个Laravel项目的方法详解
2017/11/14 PHP
Smarty模板语法详解
2019/07/20 PHP
PHP基于timestamp和nonce实现的防止重放攻击方案分析
2019/07/26 PHP
setTimeout和setInterval的区别你真的了解吗?
2011/03/31 Javascript
关于jQuery参考实例2.0 用jQuery选择元素
2013/04/07 Javascript
JQuery文字列表向上滚动的代码
2013/11/13 Javascript
Javascript:为input设置readOnly属性(示例讲解)
2013/12/25 Javascript
理解javascript中的严格模式
2016/02/01 Javascript
Active控件问题小结(附解决办法)
2016/06/09 Javascript
Vue.js快速入门教程
2016/09/07 Javascript
JavaScript正则表达式小结(test|match|search|replace|split|exec)
2016/12/08 Javascript
webpack4.x打包过程详解
2018/07/18 Javascript
vue中使用WX-JSSDK的两种方法(推荐)
2020/01/18 Javascript
[56:00]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第二场
2018/04/10 DOTA
Odoo中如何生成唯一不重复的序列号详解
2018/02/10 Python
tensorflow 加载部分变量的实例讲解
2018/07/27 Python
Python pyautogui模块实现鼠标键盘自动化方法详解
2020/02/17 Python
python中urllib.request和requests的使用及区别详解
2020/05/05 Python
PyQt5实现仿QQ贴边隐藏功能的实例代码
2020/05/24 Python
如何解决python多种版本冲突问题
2020/10/13 Python
CSS3属性box-shadow使用详细教程
2012/01/21 HTML / CSS
计算机大学生的自我评价
2013/10/15 职场文书
纺织工程专业个人求职信范文
2014/01/27 职场文书
研究生导师推荐信
2014/09/06 职场文书
2015年元旦文艺晚会总结(学院)
2014/11/28 职场文书
2014小学语文教学工作总结
2014/12/17 职场文书
高中生毕业评语
2014/12/30 职场文书
酒会邀请函
2015/01/31 职场文书
煤矿百日安全活动总结
2015/05/07 职场文书
2015年小学数学教师个人工作总结
2015/05/25 职场文书
python文件名批量重命名脚本实例代码
2021/04/22 Python
CSS实现切角+边框+投影+内容背景色渐变效果
2021/11/01 HTML / CSS
「玫瑰之王的葬礼」舞台剧主视觉图公开
2022/03/21 日漫