hn-failte's blog hn-failte's blog
首页
  • 前端文章

    • JavaScript
    • Vue
    • React
    • Webpack
    • 混合开发
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《React》笔记
    • 《TypeScript 从零实现 axios》
    • 《Git》学习笔记
    • TypeScript笔记
    • JS设计模式总结笔记
  • HTML&CSS
  • HTML
  • CSS
  • CSS预处理
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 算法
  • 数据库
  • 操作系统
  • 工具
  • 学习
  • 面试
  • 心情杂货
  • 前端相关
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

hn-failte

前端cv仔
首页
  • 前端文章

    • JavaScript
    • Vue
    • React
    • Webpack
    • 混合开发
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《React》笔记
    • 《TypeScript 从零实现 axios》
    • 《Git》学习笔记
    • TypeScript笔记
    • JS设计模式总结笔记
  • HTML&CSS
  • HTML
  • CSS
  • CSS预处理
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 算法
  • 数据库
  • 操作系统
  • 工具
  • 学习
  • 面试
  • 心情杂货
  • 前端相关
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Webpack

  • React

  • JavaScript

    • new命令原理
    • ES5面向对象
    • ES6面向对象
    • 多种数组去重性能对比
    • JS随机打乱数组
    • 判断是否为移动端浏览器
    • 将一维数组按指定长度转为二维数组
    • 防抖与节流函数
    • JS获取和修改url参数
    • 比typeof运算符更准确的类型判断
    • 三级目录

    • JavaScript

      • JavaScript之函数尾调用与函数尾递归
      • 一种实现call、apply、bind的方法
      • 实现call、apply、bind
      • JavaScript闭包详解
      • 窗口间的通信与iframe跨域
      • JavaScript逻辑运算符“&&”和“||”短路原则的应用
      • Object原型梳理
      • JavaScript设计模式之发布&订阅模式
      • JavaScript核心:两链一包
      • JavaScript之正则
      • 字符串拼接性能优化
      • JavaScript变量转换
  • Vue

  • 混合开发

  • 学习笔记

  • 微信小程序

  • 前端
  • JavaScript
  • JavaScript
hn-failte
2018-09-14

JavaScript闭包详解

# 变量作用域

首先来了解一下Javascript中变量的作用域,除了常见的普通变量外,对象和函数也是一种变量。变量分为局部变量和全局变量。

# 局部变量

局部变量就是指在函数内部定义的变量,作用域是函数内部网,此变量通常只能在函数内部访问,和外界是区分开的,所以变量名即使和外部的重复,也是两个独立的变量,不会相互影响。局部变量在函数执行是创建,执行完后销毁。

# 全局变量

全局变量就是函数外部定义的变量,作用域是网页中的所有脚本和函数,它们都能够访问,全局变量是页面加载时创建,页面关闭后销毁。

综合举例:

var a = 0;
function fun1() {
	var a = 1;
	b = 2;
}
1
2
3
4
5

这里的 var a = 0; 就是全局变量,var a = 1; 是局部变量,虽然名字重复,但这里是两个独立变量,但是还是不建议出现重复,提高代码可读性;b = 2; 也是全局变量,因为规定函数内部申明的变量,如果不加 var,即会被认为是全局变量,尤其这点需要小心。

# 闭包

先通俗的总结一下,闭包就是一个可以访问其他函数内部变量的函数,即一个定义在函数内部的函数,也叫内嵌函数。

其次,是闭包的作用,因为通常情况函数内部变量是无法在外部访问的,即全局变量也局部变量的区别,而闭包,就实现了能在外部访问某函数内部变量的功能,让这些变量值始终保存在内存中。

然后,来讲一下如何实现闭包。有以下代码:

function fun1() {
	var a = 1;           //定义一个局部变量
	function fun2() {    //这里的 fun2() 就是闭包
		alert(a);    //fun2() 是 fun1()的子函数,所以能访问之前定义的局部变量,这个是关键
	}
	return fun2;         //然后通过这里,把之前得到的局部变量成功返回到外部去
}
fun1();                      //正常执行函数
var result = fun1();         //将内部变量传递出去,传给变量 result
result();                    //执行这个函数实现对局部变量的访问
1
2
3
4
5
6
7
8
9
10

当然形式不止这一种,万变不离其宗,最后实现的功能是一样的,例如下面的方法也是可行的:

function fun1() {
	var a = 1;
	return function(){
		alert(a);
	};
}
fun1();
var result = fun1();
result();
1
2
3
4
5
6
7
8
9

# 注意

也许在很多文章中都能看到这句话“避免滥用闭包”,的确,由于闭包会使一些变量一直保存在内存中,所以如果大量使用的话就会消耗大量内存,影响网页性能。

同时,由于闭包的特性,还会在外部改变函数的内部变量值,有时候这是很危险的,举个例子:

function fun1() {
	var a = 1;
	function fun2() {
		a++;
	}
	alert(a);
	return fun2;
}
fun1();                   //函数正常执行,输出 1
var change = fun1();
change();                 //在外部执行这个函数后,函数内部变量 a 的值就被改变了,输出 2
1
2
3
4
5
6
7
8
9
10
11
编辑 (opens new window)
#Closure
上次更新: 2021/08/05, 12:37:41
实现call、apply、bind
窗口间的通信与iframe跨域

← 实现call、apply、bind 窗口间的通信与iframe跨域→

最近更新
01
基于 Taro 的微信小程序优化指南
02-16
02
搭建一个极简混合开发架构
08-03
03
使用State Hook
04-06
更多文章>
Theme by Vdoing | Copyright © 2017-2023 hn-failte | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式