JavaScript高级__深入了解闭包

理解闭包

1.如何产生闭包

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

2.闭包到底是什么

闭包是嵌套的内部函数

包含被引用变量(函数)的对象

注意:闭包存在于嵌套的内部函数中

3.产生闭包的条件

函数嵌套

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

function fn1() {
  // 此时闭包就已经产生了(函数提升,内部函数对象已经创建了)
  var a =2
  function fn2() {
    a++
    console.log(a)
  }
  return fn2
}
var f = fn1()
f() // 3
f() // 4
f = null // 闭包死亡(包含闭包的函数对象成为垃圾对象)

常见的闭包

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

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

闭包的作用

1.延长局部变量的生命周期

2.从外部可以(间接)操作函数内部的局部变量

闭包的生命周期

1.产生:在嵌套内部函数定义执行完成就产生了(不是在调用时)

2.死亡:在嵌套内部函数成为垃圾对象时

闭包的应用

自定义JS模块

*具有特定功能得js文件

*将所有的数据和功能都封装在一个函数内部(私有的)

*只向外暴露一个包含n个方法的对象或函数

*模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能

案例一

function myModule() {
  // 私有变量
  var msg = 'Hello World'
  // 操作私有变量的函数
  function upperCase() {
    console.log('upperCase()' + msg.toUpperCase())
  }
  function lowerCase() {
    console.log('lowerCase()' + msg.toLowerCase())
  }
  // 向外部暴露对象(给外部使用的方法)
  return {
    upperCase: upperCase,
    lowerCase: lowerCase
  }
}

案例二

(function () {
  // 私有变量
  var msg = 'Hello World'
  // 操作私有变量的函数
  function upperCase() {
    console.log('upperCase()' + msg.toUpperCase())
  }
  function lowerCase() {
    console.log('lowerCase()' + msg.toLowerCase())
  }
  // 直接挂在window上
  window.myModule = {
    upperCase: upperCase,
    lowerCase: lowerCase
  }
})()

闭包的缺点以及解决

1.缺点

  *函数执行完后,函数内的局部变量没有释放,占用内存时间变长

  *容易造成内存泄漏

2.解决

  *能不用闭包就不用

  *及时释放 (赋值null)

闭包代码案例

代码一

var name = "window"
var obj = {
  name : 'object',
  getName : function() {
    return function() {
      return this.name;
    }
  }
}
console.log(obj.getName()()) // window

代码二

var name = "window"
var obj = {
  name : 'object',
  getName : function() {
    var that = this
    return function() {
      return that.name
    }
  }
}
console.log(obj.getName()()) // object

代码三

function fun(n, o) {
  console.log(o)
  return {
    fun: function(m) {
      return fun(m, n)
    }
  }
}
var aa = fun(0); // undefined
aa.fun(1); // 0
aa.fun(2); // 0
aa.fun(3); // 0

var bb = fun(0).fun(1).fun(2).fun(3); // undefined 0 1 2

var cc = fun(0).fun(1); // undefined 0
cc.fun(2); // 1
cc.fun(3); // 1

内存溢出与内存泄漏

1.内存溢出

  *一种程序运行出现的错误

  *当程序运行需要的内存超过了剩余的内存时,就抛出内存溢出的错误

2.内存泄漏

  *占用的内存没有及时释放

  *内存泄漏积累多了就容易导致内存溢出

  *常见的内存泄漏

    i意外的全局变量

    ii没有及时清理的计时器或回调函数

    iii闭包

posted @ 2021-04-30 11:43  七度丢失的梦  阅读(63)  评论(0编辑  收藏  举报