前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航

浅谈闭包

首页
2017-03-22 14:24:08
Front-End
JavaScript闭包

闭包的形成跟变量的作用域以及变量的生存周期密切相关

# 一、变量的作用域,是指变量的有效范围

  • 当在函数中声明一个变量的时候,如果该变量前面没有带上关键字 var,这个变量就会成为全局变量 ,这当然是一种很容易造成命名冲突的做法。 另外一种情况是用 var 关键字在函数中声明变量,这时候的变量即是局部变量,只有在该函数内部才能访问到这个变量,在函数外面是访问不到的。

例:变量的搜索是从内到外而非从外到 内的

var a=1;
var func1 = function(){ 
    var b=2;
    var func2 = function(){ 
        var c=3;
        console.log ( b ); // 输出:2 
        console.log ( a );// 输出:1
    }
    func2();
    console.log(c);//输出:Uncaught ReferenceError: c is not defined
}; 
func1();
@前端进阶之旅: 代码已经复制到剪贴板

# 二、变量的生存周期

  • 对于全局变量来说,全局变量的生存周期当然是的永久,除非我们主动销毁这个全局变量。
  • 而对于在函数内用var关键字声明的局部变量来说,当退出函数时,这些局部变量即失去了 它们的价值,它们都会随着函数的调用的结束而销毁

例一:

var func = function(){ 
    var a=1;
    return function(){ 
        a++;
        console.log(a);
    } 
};
var f=func();
f();// 输出:2 
f();// 输出:3
f();// 输出:4
f();// 输出:5
@前端进阶之旅: 代码已经复制到剪贴板
  • 跟我们之前的结论相反,上面的例子在当退出函数后,局部变量 a 并没有消失,而是似乎一直在某个地方 存活着。这是因为当执行 var f = func();时,f 返回了一个名函数的引用,它可以问到 func() 被调用时产生的环境,而局部变量 a 一直处在这个环境里。既然外局部变量所在的环境还能被外 界访问,这个局部变量就有了不被销毁的理由。在这里生了一个闭包结构,局部变量的声明看起来被延续了。

例二,假设页面上有 5 个 div 节点,我们通过循环来给每个 div绑定 onclick 事件,按照索引顺序,点击第 1 个 div 时弹出 0,点击第 2 个 div 时出 1,以此类

var nodes = document.getElementsByTagName( 'div' );
for(var i=0,len=nodes.length;i<len;i++){ 
    nodes[ i ].onclick = function(){
        alert(i); 
    }
};
fe
  • 一、变量的作用域,是指变量的有效范围
  • 二、变量的生存周期
  • 三、闭包的作用
    • 1、封装变量—-闭包可以帮助一些不需要暴露在全局的变量封装成“私有变量”
    • 2、延续局部变量的寿命
  • 四、闭包与内存泄漏

← ES6编码风格Vue学习总结(一) →