闭包

  • 闭包已关闭评论
  • 180 次浏览
  • A+
所属分类:Web前端
摘要

使用chrome调试查看理解一 — 闭包是嵌套的内部函数理解二 — 闭包是包含被引用变量(函数)的对象


闭包理解

如何产生闭包

  • 当一个嵌套的内部(子)函数引用了嵌套外部(父)函数的变量(函数)时--就产生了闭包

闭包是什么

  • 使用chrome调试查看

  • 理解一 -- 闭包是嵌套的内部函数

  • 理解二 -- 闭包是包含被引用变量(函数)的对象

  • 闭包存在于嵌套的内部函数中

  • 产生闭包的条件

  • 函数嵌套

  • 内部函数引用了外部函数的数据(变量或函数)

<script>     function fn1() {         var a = 3;         function fn2() {             console.log(a);         }         fn2();     }     fn1(); </script> 

闭包

常见闭包

将函数作为另一个函数的返回值

function fn1() {     var a = 2;     function fn2() {         a++;         console.log(a);     }     return fn2; } var f = fn1(); f();    //3--fn1的返回值是fn2--相当于调用了fn2()--相当于fn1()() f();    //4--闭包不会消失--第一次fn1()执行时--闭包内的数据是3--第二次执行时就是4 

将函数作为实参传递给另一个函数调用

function showDelay(msg, time) {     setTimeout(function () {         console.log(msg);   //闭包     }, time); } showDelay('zao', 2000); 

闭包

闭包的作用

  • 使用函数内部的变量在函数执行完后--仍然存活在内存中--延长了局部变量的生命周期

  • 让函数外部可以操作(读写)到函数内部的数据--变量/函数

问题

  • 函数执行完--函数内部声明的局部变量是否还存在--一般不存在,存在于闭包中的变量才可能存在
  • 在函数外部能直接访问函数内部的局部变量吗--不能,但可以通过闭包让外部操作它

闭包的生命周期

  • 产生--在嵌套内部函数定义执行完时就产生了
  • 死亡--在嵌套内部函数成为垃圾对象时
function fn1(){     // 闭包产生--函数提升--内部函数已经创建了     var a = 2;     function fn2(){         a++;         console.log(a);     }     return fn2; } //只要有变量引用fn1()闭包就一直存在 var f = fn1(); f(); f(); //闭包死亡--包含闭包的函数成为垃圾对象 f = null; 

闭包的应用

定义JS模块

  • 具有特定功能的js文件
  • 将所有数据和功能都封装在一个函数内部--私有
  • 只向外暴露一个包含n个方法的对象或函数
  • 模块的使用者--只需通过模块暴露的对象调用方法来实现对应的功能
//JS文件 function myMoudle() {     var msg = 'zaoya';     function doSomething() {         //toUpperCase--字符串转换为大写         console.log('doSomething()' + msg.toUpperCase());     }     function doOtherthing() {         //toLowerCase--字符串转换为小写         console.log('doOtherthing()' + msg.toLowerCase());     }     //向外暴露对象     return {         doSomething: doSomething,         doOtherthing: doOtherthing     } }  //html文件 <script src="myMoudle.js"></script> <script>     let fn = myMoudle(); 	fn.doSomething(); 	fn.doOtherthing(); </script> 
//JS文件 (function myMoudle1() {     let msg = 'zaozao';     function doSomething() {         console.log('doSomething()' + msg.toUpperCase);     };     function doOtherthing() {         console.log('doOtherthing()' + msg.toLowerCase);     }     window.myMoudle1 = {         doSomething: doSomething,         doOtherthing: doOtherthing     } })()  //html文件 <script src="myMoudle1.js"></script> <script> 	myMoudle1.doSomething(); 	myMoudle1.doOtherthing(); </script> 

闭包的缺点

缺点

  • 函数执行完后--函数内的局部变量没有释放--占用内存时间会变长
  • 容易造成内存泄漏

解决

  • 能不用闭包就不用闭包
  • 及时释放

内存溢出

  • 一种程序运行出现的错误
  • 当程序运行需要的内存超过了剩余的内存时--就会抛出内存溢出的错误

内存泄漏

  • 占用的内存没有及时释放
  • 内存泄漏积累多了就容易导致内存溢出

常见内存泄漏

  • 意外的全局变量
  • 没有及时清理的计时器或回调函数
  • 闭包

面试题

var name = 'The Window'; var object = {     name: 'My Object',     getNameFunc: function () {         return function () {             return this.name;         }     } } //object.getNameFunc()--是对象调用--通过object调用--this为object //通过object.getNameFunc()--调用函数--object.getNameFunc()()--是函数调用--this为window alert(object.getNameFunc()());  //The Window var name2 = 'The Window'; var object = {     name2: 'My Object',            var that = this;         return function () {             return that.name2;         }     } } //object.getNameFunc()--是对象调用--通过object调用--this为object //object.getNameFunc()()--中that是object.getNameFunc()的this--指向object alert(object.getNameFunc()())       //My Object 
  • 版权声明:本站原创文章,于2023年4月25日16:03:34,由 发表,共 2470 字。
  • 转载请注明:闭包 - 张拓的天空