Skip to content

闭包

🕒 Published at:

什么是闭包

闭包(closure): 可以访问其他函数内部定义的变量的函数。

成哥:可以访问某个函数内部变量的函数被 return 到了外部,导致作用域链不释放的一个模式叫闭包

https://wangdoc.com/javascript/types/function#闭包

闭包的作用

1. 私有化变量

函数累加器、累减器

js
function counter() {
  let count = 0
  function increase() {
    count++
    console.log(count)
    return count
  }
  function decrease() {
    count--
    console.log(count)
    return count
  }
  return {
    increase,
    decrease,
  }
}

const { increase, decrease } = counter()
increase()
increase()
increase()
decrease()
  1. 模块化开发,防止污染全局变量
  2. 可以做缓存(存储结构)

闭包的缺点

会造成作用域链不释放,需要慎重使用

闭包漏洞

js
const o = (function () {
  const obj = {
    a: 1,
    b: 2,
  }
  return {
    get(k) {
      return obj[k]
    },
  }
})()

如何在不改变上面代码的情况下,修改obj对象?

js
Object.defineProperty(Object.prototype, 'abc', {
  get() {
    return this
  }
})
let res = o.get('abc')
console.log(res)

res.a = 111
res.b = 222

console.log(o.get('a'))
console.log(o.get('b'))

第一种防御方法

将obj的prototype设置为null

js
const o = (function () {
  const obj = {
    a: 1,
    b: 2,
  }
  Object.setPrototypeOf(obj,null)
  return {
    get(k) {
      return obj[k]
    },
  }
})()

第二种防御方法

在get中判断是否是本来的属性,而不是原型上的属性

js
const o = (function () {
  const obj = {
    a: 1,
    b: 2,
  }
  return {
    get(k) {
      if (obj.hasOwnProperty(k)) {
        return obj[k]
      }
      return undefined
    },
  }
})()