Javascript 中闭包(Closure)的探索(三)-私有函数中的this

简介:

在上一篇文章中,私有函数里给公有变量this.publicMem 赋值并没有达到预期的效果。(示例代码参见Javascript 中闭包(Closure)的探索(二)-私有变量和函数

 

原因在于每个函数被调用时,会产生自己的scope,在此scope中,会生成自己函数内使用的变量,方法等等。

对于公有的变量和方法(如上篇文章例子中的this.publicMem和this.callprivateFunc等)会在函数ClassFunc被new出来时一起加入到ClassFunc的scope中,因此在函数callprivateFunc中的this指针就是指向当前new出来的ClassFunc对象。

而对于私有函数privateFunc,是在被调用时才形成自己的scope的,由于这个函数不在ClassFunc的scope中,因此其中的this指针就是指向全局的window对象。

验证代码如下:

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
34
35
36
37
38
39
<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!" ;
             // 相当于给window对象的publicMem属性赋值
             // 因为当前window对象不存在publicMem属性,所以新建了publicMem属性。
             // 此时test对象的this.publicMem没变
             this .publicMem = "public changed!" ;
         }
 
         this .callprivateFunc = function () {
             privateFunc();
         }
     }
 
     function  closureTestClick() {
         var  test = new  ClassFunc();
         // 变更前
         alert( "privateMem="  + test.getprivateMem());
         alert( "publicMem="  + test.publicMem);
         // 此时window.publicMem为undefined
         alert( "publicMem="  + window.publicMem);
         test.callprivateFunc(test);
         // 变更后
         alert( "privateMem="  + test.getprivateMem());
         alert( "publicMem="  + test.publicMem);
         // 此时window.publicMem为"public changed!"
         alert( "publicMem="  + window.publicMem);
     }
</script>

如果需要在私有函数中利用this操作当前对象test,而非window对象。可以利用javascript内置的两个方法callapply,即显示的将对象传递给私有函数privateFunc。

代码如下:

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
34
35
36
37
38
39
<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!" ;
                 this .publicMem = "public changed!" ;
             }
 
             this .callprivateFunc = function () {
                 privateFunc.apply( this );
                 //或者
                 //privateFunc.call(this);
             }
         }
 
         function  closureTestClick() {
             var  test = new  ClassFunc();
             // 变更前
             alert( "privateMem="  + test.getprivateMem());
             alert( "publicMem="  + test.publicMem);
             // 此时window.publicMem为undefined
             alert( "publicMem="  + window.publicMem);
             test.callprivateFunc(test);
             // 变更后
             alert( "privateMem="  + test.getprivateMem());
             // 此时test.publicMem被改变了
             alert( "publicMem="  + test.publicMem);
             // 此时window.publicMem为undefined
             alert( "publicMem="  + window.publicMem);
         }
     </script>

因此,我们在js中使用私有函数的时候一定要注意这个特点,这也是js和其他真正面向对象的语言(C#,java等)的区别之一吧!

如有理解不对的地方,还希望各位不吝指教!



本文转自wang_yb博客园博客,原文链接:http://www.cnblogs.com/wang_yb/archive/2010/05/07/1729646.html,如需转载请自行联系原作者

目录
相关文章
|
10天前
|
JavaScript
JS实现多条件搜索函数
JS封装的多条件搜索
|
1月前
|
缓存 自然语言处理 JavaScript
JavaScript中闭包详解+举例,闭包的各种实践场景:高级技巧与实用指南
闭包是JavaScript中不可或缺的部分,它不仅可以增强代码的可维护性,还能在模块化、回调处理等场景中发挥巨大作用。然而,闭包的强大也意味着需要谨慎使用,避免潜在的性能问题和内存泄漏。通过对闭包原理的深入理解以及在实际项目中的灵活应用,你将能够更加高效地编写出简洁且功能强大的代码。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
1月前
|
JavaScript 前端开发 Java
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
柯里化是一种强大的函数式编程技术,它通过将函数分解为单参数形式,实现了灵活性与可复用性的统一。无论是参数复用、延迟执行,还是函数组合,柯里化都为现代编程提供了极大的便利。 从 Redux 的选择器优化到复杂的数据流处理,再到深度嵌套的函数优化,柯里化在实际开发中展现出了非凡的价值。如果你希望编写更简洁、更优雅的代码,柯里化无疑是一个值得深入学习和实践的工具。从简单的实现到复杂的应用,希望这篇博客能为你揭开柯里化的奥秘,助力你的开发之旅! 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
2月前
|
自然语言处理 JavaScript 前端开发
当面试官再问我JS闭包时,我能答出来的都在这里了。
闭包(Closure)是前端面试中的高频考点,广泛应用于函数式编程中。它不仅指函数内部定义的函数,还涉及内存管理、作用域链和垃圾回收机制。闭包可以让函数访问其外部作用域的变量,但也可能引发内存泄漏等问题。通过合理使用闭包,可以实现模块化、高阶函数和回调函数等应用场景。然而,滥用闭包可能导致代码复杂度增加、调试困难以及潜在的性能问题。为了避免这些问题,开发时应谨慎处理闭包,避免不必要的嵌套,并及时清理不再使用的变量和监听器。
142 16
当面试官再问我JS闭包时,我能答出来的都在这里了。
|
2月前
|
JavaScript 前端开发
JavaWeb JavaScript ③ JS的流程控制和函数
通过本文的详细介绍,您可以深入理解JavaScript的流程控制和函数的使用,进而编写出高效、可维护的代码。
84 32
|
2月前
|
前端开发 JavaScript Java
JavaScript闭包深入剖析:性能剖析与优化技巧
JavaScript 闭包是强大而灵活的特性,广泛应用于数据封装、函数柯里化和事件处理等场景。闭包通过保存外部作用域的变量,实现了私有变量和方法的创建,提升了代码的安全性和可维护性。然而,闭包也可能带来性能问题,如内存泄漏和执行效率下降。为优化闭包性能,建议采取以下策略:及时解除对不再使用的闭包变量的引用,减少闭包的创建次数,使用 WeakMap 管理弱引用,以及优化闭包结构以减少作用域链查找的开销。在实际开发中,无论是 Web 前端还是 Node.js 后端,这些优化措施都能显著提升程序的性能和稳定性。
139 70
|
5月前
|
存储 缓存 自然语言处理
掌握JavaScript闭包,提升代码质量与性能
掌握JavaScript闭包,提升代码质量与性能
|
5月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包(Closures)
深入理解JavaScript中的闭包(Closures)
|
5月前
|
存储 自然语言处理 JavaScript
深入理解JavaScript的闭包(Closures)
深入理解JavaScript的闭包(Closures)
75 0
|
5月前
|
前端开发 JavaScript 开发者
除了 Generator 函数,还有哪些 JavaScript 异步编程解决方案?
【10月更文挑战第30天】开发者可以根据具体的项目情况选择合适的方式来处理异步操作,以实现高效、可读和易于维护的代码。