JS笔记《闭包》

46 阅读1分钟

概述

  • JS有两种作用域:全局作用域函数作用域(块级作用域不在此讨论范围)。因为作用域链的原因,函数内部可以读取全局变量,但函数外部却无法读取到函数内的变量。
  • 所谓闭包就是能够读取其他函数内部变量的函数。只有函数内部的子函数才可以读取内部变量,因此可以把闭包理解成定义在一个函数内部的函数。闭包最大的特点就是,它可以记住诞生的环境(函数执行上下文)。
function f1(){
   var a = 999;
   
   function f2(){
     console.log(a);  // f2的作用域可以访问f1内部的变量
   }
   
   return f2;   // 因为f2中用了f1中的a变量,所以f2的执行栈为[f2的AO, f1的AO{a: 999}]
}
var res = f1(); // 获取f2函数
res(); // 999   // 执行就可以访问到f1中的a变量

闭包的用处

  • 可以读取函数内部的变量,让这些变量始终保持在内存中。
function increment(start){
  return function(){
   return start++;
  }
}

let inc = increment(5);  
inc(); // 5
inc(); // 6
  • 封装对象的私有属性和私有方法。
function Person(name){
  var _age;   // 私有属性
  
  function setAge(n){   // 私有方法
    _age = n;
  }
  
  function getAge(){    // 私有方法
    return _age;
  }
  
  return {
    name,
    setAge,
    getAge
  }
}
var p = Person('张三');
p.setAge(20);
p.getAge(); // 20

闭包的弊端

  • 外层函数每次运行时,都会生成一个新的闭包,而这个闭包又会保留了外层函数内部变量,所以内存消耗过大。只要闭包没有被垃圾回收机制清除,则会一直存在在内存中,容易造成内存泄漏。