美文网首页
前端技术名词之闭包

前端技术名词之闭包

作者: 冰冰啦 | 来源:发表于2019-03-30 21:00 被阅读0次

闭包的概念

函数执行时形成一个私有作用域(栈内存), 保护私有变量不受外部的影响, 这种保护机制称为闭包

大部分的开发者认为的闭包: 函数执行时形成一个不销毁的私有作用域, 这就是闭包

关于闭包的技术名词

function fn() {
  return function() {
    ...
  }
}
let fn2 = fn()

因为fn内部return的函数被外部使用, 所以堆内存不会被释放

这种闭包有个高大上的名字叫柯理化函数

let utils = !function() {
  return {
    ...
  }
}()

和上面类似, 这种闭包也有个高大上的名字叫惰性函数

但是, 在真实项目中, 为了保证js的性能(堆栈内存的性能优化), 应该尽可能的减少闭包的使用

闭包的作用

  1. 闭包可以保护私有变量不受外界的干扰
  2. 闭包可以形成不销毁的栈内存, 把一些值保存下来, 来供后面使用

闭包应用实战(循环绑定事件, 索引触发)

假如我们页面上有三个按钮, 编号为1,2,3, html结构如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div class="button-wrapper">
    <button id="btn">1</button>
    <button id="btn">2</button>
    <button id="btn">3</button>
  </div>
</body>
</html>

我们希望点击button, 把它们对应的索引打出来(从0开始)

我们可能会写出这样的js代码

let buttons = document.querySelectorAll('#btn')
for(var i = 0;i < buttons.length;i++) {
  buttons[i].onclick = function() {
    console.log(i)
  }
}

但是, 当我们点击每个按钮时, 发现无论点击哪个按钮, 都会打印3

造成这样的结果是因为, 当我们点击元素时, 会执行console.log(i), 函数作用域内没有i变量, 所以会按照作用域链向上查找, 直到找到了全局变量i, 但是i已经经历过了for循环, 所以值为3

解决方案1: 利用自定义属性记录当前索引

let buttons = document.querySelectorAll('#btn')
for(var i = 0;i < buttons.length;i++) {
  buttons[i].Index = i
  buttons[i].onclick = function() {
    console.log(this.Index)
  }
}

自定义属性非常有用里
解决方案2: 把var改为let

let buttons = document.querySelectorAll('#btn')
for(let i = 0;i < buttons.length;i++) {
  buttons[i].onclick = function() {
    console.log(i)
  }
}
console.log(i)

let具有块级作用域, 推荐使用
解决方案3: 利用闭包的保存机制(栈内存可以保存值)

let buttons = document.querySelectorAll('#btn')

for(var i = 0;i < buttons.length;i++) {
  buttons[i].onclick = (function(i) {
  //这里执行时形成一个私有作用域, 内存不会被释放, 因为返回的函数被外部占用了. 
  //这个私有作用域把每个i保存了下来
    return function() {
      console.log(i)
    }
  })(i)
}

这种方案特别耗费性能, 所以不推荐

相关文章

  • 前端技术名词之闭包

    闭包的概念 函数执行时形成一个私有作用域(栈内存), 保护私有变量不受外部的影响, 这种保护机制称为闭包 大部分的...

  • 2016/12/27

    技术 python中的闭包 从 Web 前端到客户端

  • 好程序员web前端培训分享web前端面试题JS篇之闭包

    好程序员web前端培训分享web前端面试题JS篇之闭包,JS中关于闭包的相关知识。如果你想参加web前面工作,那么...

  • 前端面试必问内容

    跨域如何实现 闭包 链式继承 http状态码 前端优化 对前端新技术的了解 react、vue、angular 前...

  • 闭包

    一、闭包技术详解 1.1 什么是闭包? 闭包实际上是一种函数,所以闭包技术也是函数技术的一种;闭包能做的事情函数几...

  • 闭包是什么?

    学习前端的童鞋,通常会听到闭包这个名词,不了解的童鞋会觉得这货真高大上。实际上 闭包并没有这么高深莫测,小白也可...

  • python函数之闭包

    目录 python函数之闭包什么是闭包python中的namespace闭包的条件闭包的优点 python函数之闭...

  • 闭包

    title: 闭包date: 2018-05-27 23:00:00tags: 闭包categories: 前端 ...

  • JS-读懂闭包

    长久以来,闭包是前端同学面试必考的问题。会用闭包也成了高级前端开发者的标志,今天就来彻底弄清楚闭包的每一个细节。 ...

  • 前端面试常见问题

    前端技术面的考点无外乎:事件原理,闭包,调用栈,Promise,ES6,工程化,webpack,性能优化,跨域,安...

网友评论

      本文标题:前端技术名词之闭包

      本文链接:https://www.haomeiwen.com/subject/vmyrbqtx.html