对闭包的理解

what:一个函数能够访问其函数外部作用域中的变量

三大特点:

  1.函数嵌套函数

  2.内部函数可以访问外部函数的变量

  3.参数和变量不会被回收

举例:

function test () {
   var a = 1;
   return function () {
      alert(a);  
   }  
}

var try = test ();
try(); // 弹出a的值

  

作用:可以通过闭包,设计私有变量及方法

(function(){
   var name="wangyu";
   Person=function (val) {
    name=val;
   }
   Person.prototype.setName=function(val){
    name=val;
   }
   Person.prototype.getName=function () {
    return name;
   }
  })();
  var person1=new Person("sj");
  alert(this.name)//undefined 因为在function作用域外不能访问
  alert(person1.getName());//sj


  

var aaa = (function(){
  var a = 1;
  function bbb(){
    a++;
    alert(a);
  }
  function ccc(){
    a++;
    alert(a);
  }
  return {
    b:bbb,    //json结构
    c:ccc
  }
 })();
 alert(aaa.a)//undefined 
 aaa.b();  //2
 aaa.c()  //3

总结:

  1.闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建两一个函数,通过另一个函数访问这个函数的局部变量。

  2.闭包的缺点:会常驻内存,会增大内存使用量,使用不当很容易造成内存泄漏

  3.其实写的每一个函数都可以算作闭包,即使是全局函数,访问函数外部的全局变量时,就是闭包的体现

常见面试题:

  1.for循环中打印

for (var i = 0; i < 4; i++) {
  setTimeout(function() {
    console.log(i);
  }, 300);
}

上边打印出来的都是 4, 可能部分人会认为打印的是 0,1,2,3

原因:js 执行的时候首先会先执行主线程,异步相关的会存到异步队列里,当主线程执行完毕开始执行异步队列, 主线程执行完毕后,此时 i 的值为 4,说以在执行异步队列的时候,打印出来的都是 4(这里需要大家对 event loop 有所了解(js 的事件循环机制))

如何修改使其正常打印:(使用闭包使其正常打印)

//方法一:
for (var i = 0; i < 4; i++) {
  setTimeout(
    (function(i) {
      return function() {
        console.log(i);
      };
    })(i),
    300
  );
}

  2.真实获取多个元素并添加点击事件

var op = document.querySelectorAll("p");
for (var j = 0; j < op.length; j++) {
  op[j].onclick = function() {
    alert(j);
  };
}

//alert出来的值是一样的
// 解决办法一:
for (var j = 0; j < op.length; j++) {
  (function(j) {
    op[j].onclick = function() {
      alert(j);
    };
  })(j);
}
// 解决办法二:
for (var j = 0; j < op.length; j++) {
  op[j].onclick = (function(j) {
    return function() {
      alert(j);
    };
  })(j);
}

  

posted on 2019-11-10 16:25  Diamond_xx  阅读(270)  评论(0编辑  收藏  举报

导航