【前端自学(9)】闭包和作用域链


1 闭包和作用域链

  • 闭包初步引入
//以下是一些例子
//个人理解:凡是外部变量接收一个return的函数,比如let a=hd(),那么和该函数同级的变量以及父级的变量都会被这个外部变量绑定(相当于这块内存空间直接给了外部变量)
//凡是函数调用一次,都会开辟一块新的内存空间
//没有被绑定的变量会被js垃圾回收机制自动清除
function hd () {
  let n = 1
  return function () {
    console.log(++n)
  }
}
let a = hd()
a() //2
a() //3

let b = hd()
b() //2

hd()() //2
hd()() //2


function hd2 () {
  let n = 1
  return function () {
    let m = 1
    return function () {
      console.log(++n)
      console.log(++m)
    }
  }
}
let c = hd2()()
c() //2 2
c() //3 3

function hd3 () {
  let n = 1
  return function () { //注意n被绑定给了b,而m没有
    let m = 1
    function show () {
      console.log(++m)
      console.log(++n)
    }
    show()
  }
}

let d = hd3()
d() //2 2
d() //2 3
  • 考虑构造函数
function test () {
  let a = 1
  this.sum = function () {
    console.log(++a)
  }
}
let obj = new test()
obj.sum() //2
obj.sum() //3

//上面的构造函数等价于
function test2 () {
  let a = 1
  return function sum () {
    console.log(++a)
  }
}
let obj2 = test2() //可以写成let obj2 = new test2()
obj2() //2
obj2() //3
  • 区分var和let
let arr = []
for (var i = 1; i <= 3; i++) {
  arr.push(function () {
    return i
  })
}
console.log(arr[0]()) //4

let arr2 = []
for (let i = 1; i <= 3; i++) {
  arr2.push(function () {
    return i
  })
}
console.log(arr2[0]()) //1

let arr3 = []
for (var i = 1; i <= 3; i++) {
  (function (i) {
    arr3.push(function () { //通过立即执行函数开辟内存空间,绑定i给arr3.push方法
      return i
    })
  })(i)
}
console.log(arr3[0]()) //1
  • 作用域链(顺带复习一下this)
var name = "The Window";
var object = {
  name: "My Object",
  getNameFunc: function () {
    return function () {
      return this.name;
    };
  }
};

console.log(object.getNameFunc()()); //The Window

var name2 = "The Window";
var object2 = {
  name: "My Object",
  getNameFunc: function () {
      var that = this;
    return function () {
      return that.name;
    };
  }
};

console.log(object2.getNameFunc()()); //My Object
  • 闭包就是一个函数,能够访问其他函数内部变量的函数
  • 闭包的优点
    访问其他函数内部变量,变量长期驻扎在内存中,不会被内存回收机制回收,即延长变量的生命周期,避免定义全局变量所造成的污染
  • 闭包的缺点
    由于闭包会将它的外部函数的作用域也保存在内存中,因此会比其他函数更占用内存,这样的话,如果过度使用闭包,就会有内存泄露的威胁
  • 解决闭包引起的内存泄露
    在退出函数之前,将不使用的局部变量全部删除,可以使变量赋值为null
    避免变量的循环赋值和引用
    由于jQuery考虑到了内存泄漏的潜在危害,所以它会手动释放自己指定的所有事件处理程序。只要坚持使用jQuery的事件绑定方法,就可以一定程度上避免这种特定的常见原因导致的内存泄漏
  • 闭包的使用场景
    封装功能时(需要使用私有的属性和方法),函数防抖、函数节流、函数柯里化、给元素伪数组添加事件需要使用元素的索引值。

2 总结

以上就是闭包和作用域链基础

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值