js闭包函数,作用域 闭包的内存泄漏

闭包就是能够读取其他函数内部变量的函数.

首先要讲一下就是的变量作用域.

局部变量和全局变量.

var  和 es6 中的 let 和const 

var 存在变量升级

例  b //undefind

   var b  =3

let 只在let命令所在的代码块内有效

   b //报错error

  let b=3

const 声明一个只读的常量。一旦声明,常量的值就不能改变

 b //undefind

 const b =3 

简单的闭包示例

function f1(){

    var n=999;

    function f2(){
      alert(n); // 999
    }

  }


在上面的函数中f2就是一个闭包调用了函数f1内部的局部变量,在f2中 f1内部所有的局部变量对f2都是可用的,即

  

function f1(){

    var n=999;

      var B=11

    function f2(){

      alert(n); // 999

         alert(b)   //11

    }

  }

进阶 :

在学习es6 中有这样一个函数

 var a = [];
        for (var i = 0; i < 10; i++) {
            a[i] = function () {
                console.log(i);
            };
        }
        a[6]();

 函数中输出的值为10 

var a=[];

for (var i = 0; i < 10; i++) {                                       
             function (i) {
              
             a[i] = function () {
                console.log(i);
             };
}(i); } }

 a[6]();   //6

在上面A数值中的方法就是就是一个闭包函数,用匿名自执行将i赋值到成局部变量i所以a数值中的方法是调用了匿名方法中的局部变量i,

  当然es6中的let 也可以实现

var a = [];
        for (let i = 0; i < 10; i++) {
            a[i] = function () {
                console.log(i);
            };
        }
        a[6]();  //6

变量ilet声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量

闭包的内存泄漏问题

1. 定义:一块被分配的内存既不能使用,也不能回收。从而影响性能,甚至导致程序崩溃。

 2. 起因:JavaScript的垃圾自动回收机制会按一定的策略找出那些不再继续使用的变量,释放其占有的内存。然而由于一些原因导致在这种机制下内存管理器不能正确解读JavaScript变量的生命周期,从而没有释放其内存,而也没有再被使用。

 循环引用是导致以上情况的主要原因之一。

闭包实际上非常容易造成JavaScript对象和DOM对象的隐蔽循环引用。来看看下面的例子:

  function bb(){

  const b=document.getElementById("p1");

  b.οnclick=function() {

    alert(12)

}

}

以上函数bb() 中用匿名函数创建了一个闭包。

第①句:JavaScript对象element引用了一个DOM对象(其id为“div1”); JS(element) ----> DOM(div1)

第②句:该DOM对象的onclick属性引用了匿名函数闭包,而闭包可以引用外部函数example() 的整个活动对象,包括elemnt ; DOM(div1.onclick) ---->JS(element)
由此形成了JavaScript对象和DOM对象的隐蔽循环引用。

 2.解决方法:

常用的解决方法就是在JavaScript代码段运行完之时将形成循环引用的JavaScript对象手动设置为空,切断引用。

修改的例子如下:\


function bb(){

  const b=document.getElementById("p1");

  b.οnclick=function() {

    alert(12)

}

b=null

}


或者当函数a 返回了闭包函数 b,b引用了函数a中的局部变量 ,把 a 函数赋值给一个变量d ,d执行完之后不会释放a中的局部变量.

fun a(){

  var c=1

 return fun(){

   retrun c

}

}

var d=a()

var e=d()

while (e !== '') { // process data() e = d()}

修改  

fun a(){

  var c=1

var b=0

 return fun(){

if(b==0){

   retrun c

b++

}else{

c=null  //手动清空

 retrun ''

}

 

}

}

var d=a()

var e=d()

while (e !== '' ) { // process data() e = d()}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值