Javascript 中闭包(Closure)的探索(二)-私有变量和函数

简介:

利用匿名函数形成闭包可以在javascript中实现面向对象语言中的访问权限控制。即在javascript中也能实现私有变量。

参考网址:http://www.crockford.com/javascript/private.html

 

1.构造私有变量和公有变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html xmlns= "http://www.w3.org/1999/xhtml"  >
<head>
     <title>JsClosure2</title>
     <script type= "text/javascript" >
         function  ClassFunc() {
             this .publicMem = "public" ;
             var  privateMem = "private" ;
         }
 
         function  closureTestClick() {
             var  test = new  ClassFunc();
             alert(test.publicMem);
             alert(test.privateMem);
         }
     </script>
</head>
<body>
<input type= "button"  value= "closureTest"  onclick= "closureTestClick()"  />
</body>
</html>

结果:alert(test.publicMem);可以正常显示,alert(test.privateMem);显示“undefined”。

结果分析:通过var定义的私有变量外界无法访问,如果要外界可以访问,需要构造get,set方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type= "text/javascript" >
         function  ClassFunc() {
             this .publicMem = "public" ;
             var  privateMem = "private" ;
             this .getprivateMem = function () {
                 return  privateMem;
             }
             this .setprivateMem = function (val) {
                 privateMem = val;
             }
         }
 
         function  closureTestClick() {
             var  test = new  ClassFunc();
             alert(test.getprivateMem());
             test.setprivateMem( "private changed!" );
             alert(test.getprivateMem());
         }
     </script>

结果:如预期的一样显示“private”和“private changed!”。

 

2.私有函数

与私有变量的定义类似,不是通过this来定义的函数都是私有函数。

私有函数外部无法调用,但是可以通过内部的公有函数来调用。

测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<script type= "text/javascript" >
         function  ClassFunc() {
             this .publicMem = "public" ;
             var  privateMem = "private" ;
             this .getprivateMem = function () {
                 return  privateMem;
             }
             this .setprivateMem = function (val) {
                 privateMem = val;
             }
 
             function  privateFunc() {
                 privateMem = "private changed!" ;
                 // 此处的赋值并没有如预期的那样给test.publicMem成员赋值
                 this .publicMem = "public changed!" ;
             }
 
             this .callprivateFunc = function () {
                 privateFunc();
             }
         }
 
         function  closureTestClick() {
             var  test = new  ClassFunc();
             // 变更前
             alert( "privateMem=" +test.getprivateMem());
             alert( "publicMem="  + test.publicMem);
             test.callprivateFunc();
             // 变更后
             alert( "privateMem="  + test.getprivateMem());
             alert( "publicMem="  + test.publicMem);
         }
     </script>

变更后的结果privateMem如预期一样,而publicMem仍然是“public”,并没有改变。

这是因为函数privateFunc() 中this.publicMem 的this已经不是指向test这个js对象了。

关于this的指向为什么会变,参见我的第三篇文章,介绍javascript的scope的。

本例中为了能够修改testpublicMem属性,有两个方法:

其一,也是常用的,直接在外部修改publicMem,因为publicMem是公有变量。

1
test.publicMem = "public changed!" ;

其二,在函数callprivateFunc 和privateFunc中增加一个参数,显示的传入test对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<script type= "text/javascript" >
         function  ClassFunc() {
             this .publicMem = "public" ;
             var  privateMem = "private" ;
             this .getprivateMem = function () {
                 return  privateMem;
             }
             this .setprivateMem = function (val) {
                 privateMem = val;
             }
 
             function  privateFunc(obj) {
                 privateMem = "private changed!" ;
                 // 直接给obj.publicMem赋值
                 obj.publicMem = "public changed!" ;
             }
 
             this .callprivateFunc = function (obj) {
                 privateFunc(obj);
             }
         }
 
         function  closureTestClick() {
             var  test = new  ClassFunc();
             // 变更前
             alert( "privateMem=" +test.getprivateMem());
             alert( "publicMem="  + test.publicMem);
             test.callprivateFunc(test);
             // 变更后
             alert( "privateMem="  + test.getprivateMem());
             alert( "publicMem="  + test.publicMem);
         }
     </script>
标签:  javascript学习



本文转自wang_yb博客园博客,原文链接:http://www.cnblogs.com/wang_yb/archive/2010/05/06/1729070.html,如需转载请自行联系原作者
目录
相关文章
|
18天前
|
前端开发 JavaScript Java
JavaScript闭包深入剖析:性能剖析与优化技巧
JavaScript 闭包是强大而灵活的特性,广泛应用于数据封装、函数柯里化和事件处理等场景。闭包通过保存外部作用域的变量,实现了私有变量和方法的创建,提升了代码的安全性和可维护性。然而,闭包也可能带来性能问题,如内存泄漏和执行效率下降。为优化闭包性能,建议采取以下策略:及时解除对不再使用的闭包变量的引用,减少闭包的创建次数,使用 WeakMap 管理弱引用,以及优化闭包结构以减少作用域链查找的开销。在实际开发中,无论是 Web 前端还是 Node.js 后端,这些优化措施都能显著提升程序的性能和稳定性。
111 70
|
4天前
|
自然语言处理 JavaScript 前端开发
当面试官再问我JS闭包时,我能答出来的都在这里了。
闭包(Closure)是前端面试中的高频考点,广泛应用于函数式编程中。它不仅指函数内部定义的函数,还涉及内存管理、作用域链和垃圾回收机制。闭包可以让函数访问其外部作用域的变量,但也可能引发内存泄漏等问题。通过合理使用闭包,可以实现模块化、高阶函数和回调函数等应用场景。然而,滥用闭包可能导致代码复杂度增加、调试困难以及潜在的性能问题。为了避免这些问题,开发时应谨慎处理闭包,避免不必要的嵌套,并及时清理不再使用的变量和监听器。
当面试官再问我JS闭包时,我能答出来的都在这里了。
|
18天前
|
JavaScript 前端开发
JavaWeb JavaScript ③ JS的流程控制和函数
通过本文的详细介绍,您可以深入理解JavaScript的流程控制和函数的使用,进而编写出高效、可维护的代码。
64 32
|
3月前
|
JavaScript 前端开发
js 闭包的优点和缺点
【10月更文挑战第27天】JavaScript闭包是一把双刃剑,在合理使用的情况下,它可以带来很多好处,如实现数据封装、记忆功能和模块化等;但如果不注意其缺点,如内存泄漏、变量共享和性能开销等问题,可能会导致代码出现难以调试的错误和性能问题。因此,在使用闭包时,需要谨慎权衡其优缺点,根据具体的应用场景合理地运用闭包。
150 58
|
3月前
|
JavaScript 前端开发 Java
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
本文介绍了JavaScript中常用的函数和方法,包括通用函数、Global对象函数以及数组相关函数。详细列出了每个函数的参数、返回值及使用说明,并提供了示例代码。文章强调了函数的学习应结合源码和实践,适合JavaScript初学者和进阶开发者参考。
57 2
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
|
3月前
|
缓存 JavaScript 前端开发
js 闭包
【10月更文挑战第27天】JavaScript闭包是一种强大的特性,它可以用于实现数据隐藏、记忆和缓存等功能,但在使用时也需要注意内存泄漏和变量共享等问题,以确保代码的质量和性能。
50 7
|
3月前
|
前端开发 JavaScript 开发者
除了 Generator 函数,还有哪些 JavaScript 异步编程解决方案?
【10月更文挑战第30天】开发者可以根据具体的项目情况选择合适的方式来处理异步操作,以实现高效、可读和易于维护的代码。
|
3月前
|
自然语言处理 JavaScript 前端开发
JavaScript闭包:解锁编程潜能,释放你的创造力
【10月更文挑战第25天】本文深入探讨了JavaScript中的闭包,包括其基本概念、创建方法和实践应用。闭包允许函数访问其定义时的作用域链,常用于数据封装、函数柯里化和模块化编程。文章还提供了闭包的最佳实践,帮助读者更好地理解和使用这一强大特性。
36 2
|
3月前
|
存储 缓存 自然语言处理
掌握JavaScript闭包,提升代码质量与性能
掌握JavaScript闭包,提升代码质量与性能
|
3月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包(Closures)
深入理解JavaScript中的闭包(Closures)

热门文章

最新文章

  • 1
    当面试官再问我JS闭包时,我能答出来的都在这里了。
    65
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    33
  • 3
    Node.js 中实现多任务下载的并发控制策略
    35
  • 4
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    27
  • 5
    【JavaScript】深入理解 let、var 和 const
    50
  • 6
    【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
    48
  • 7
    【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
    61
  • 8
    【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
    59
  • 9
    如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
    72
  • 10
    【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
    58