`
snake_hand
  • 浏览: 625075 次
社区版块
存档分类
最新评论

【深入JavaScript】2.闭包(读书笔记)

 
阅读更多

读《JavaScript高级程序设计》第7章有感。

一、究竟闭包是什么?

闭包是指有权访问另一个函数作用域中的变量的函数。

个人感悟:

通过书中的这句定义,按中文语法分析,说白了,闭包就是一种函数,而这种函数可以访问另一个函数作用域中的变量。

那为什么这种函数有这样牛B的功能呢?其实,它是利用了函数的作用域链。

 

二、创建闭包的常见方式:在一个函数内部创建另一个函数

function createComparisonFunction(propertyName){

  return function(object1,object2){

    var value1 = object1[propertyName];

    var value2 = object2[propertyName];

    if(value1 < value2){

      return -1;

    }else if(value1 > value2){

      return 1;

    }else{

      return 0;

    }

  };
} 

留意这个例子中标红的地方。标红处是一个内部函数的代码,而这个内部函数正是匿名函数。

这两行代码访问了外部函数中的变量propertyName。即使这个内部函数被返回了,而且是在其他地方被调用了,但它仍然可以访问变量propertyName。

之所以还能够访问这个变量,是因为这个匿名函数的作用域链中包含了createComparisonFunction()的作用域(在作用域链中是以变量对象表示)

 

三、闭包能够起什么作用?为什么闭包能够起作用?

说到这里,我们不得不回想一下之前学过的关于作用域链的知识。只有透彻理解作用域链,才能真正理解闭包起什么作用,为什么能够起作用

关于作用域链的知识,在我上一篇博文中已经详细说明,在这就不重复叙述了,我只讲关键的地方。

首先,当调用某个函数的时候,系统会为函数创建一个执行环境,并且通过复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链。而函数的活动对象作为变量对象被推入执行环境作用域链的最前端。

可见,当函数被调用时,会创建两个东西,一个是函数的执行环境,另一个则是其相应的作用域链

一般来说,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域(也就是全局执行环境的变量对象)。

但是,闭包的情况有所不同。原因就是:

 

在另一个函数内部定义的函数会将包含函数(即外部函数)的活动对象添加到它的作用域链中。

 

回到上面的例子:

function createComparisonFunction(propertyName){

  return function(object1,object2){

    var value1 = object1[propertyName];
    var value2 = object2[propertyName];

    if(value1 < value2){
      return -1;
    }else if(value1 > value2){
      return 1;
    }else{
      return 0;
    }
  };
} 

可以看出,在createComparisonFunction()函数内部定义的匿名函数的作用域链中,包含外部函数createComparisonFunction()的活动对象。

在匿名函数从createComparisonFunction()中被返回后,它的作用域链就变成了下图所示:

此时,匿名函数可以访问在createComparisonFunction()中定义的所有变量。

更重要的是,当createComparisonFunction()函数执行完毕后,也就是返回了匿名函数后,它的活动对象也不会被销毁,这是因为匿名函数的作用域链仍然在引用这个活动对象

也就是说,当createComparisonFunction()函数返回后,它的执行环境的作用域链会被销毁,但它的活动对象仍然被引用。根据JS的GC策略,因为该活动对象引用次数不为0,因此它会留在内存中,直到匿名函数被销毁后,createComparisonFunction()的活动对象才会被销毁。

 

四、闭包与变量

由上知,闭包是通过作用域链这种机制来实现的,因此,它也有着一个值得我们注意的副作用,那就是:

闭包只能取得包含函数中任何变量的最后一个值,因为闭包只是引用其作用域链上的变量对象。

例子不敲了,自己推敲一下吧哈~书上有,懒得敲了。

 

五、总结

由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存,过度使用闭包可能会导致内存占用过多,这方面要注意一下。

这本JS基础书真心好,闭包这部分得多看看。

关于闭包的一些应用将在下一篇文章讲述。

共勉。

分享到:
评论

相关推荐

    JavaScript高阶第三天.xmind

    js高阶笔记总结: 严格模式: 1.开启严格模式:"use strict" 2.不使用var关键字声明会报错 3.严格模式下普通函数的this指向undefined 高阶函数: 满足其中之一即高阶函数: 1.函数作为参数 2.函数作为返回值 ...

    javascript 高级程序设计 读书笔记(3)

    这篇读书笔记主要聚焦在第三部分,这部分通常涵盖了更高级的主题,如对象、原型、闭包以及模块化等。结合提供的"listutil.js"文件,我们可以深入探讨JavaScript中的实用工具函数和编程技巧。 首先,JavaScript的...

    原生javascript笔记.zip

    这份“原生javascript笔记”涵盖了基础到进阶的知识点,非常适合初学者和希望提升技能的开发者。下面将详细阐述其中可能包含的重要概念和技能。 1. **基础语法**:JavaScript的基础包括变量声明(`var`, `let`, `...

    javascript笔记之匿名函数和闭包.docx

    **闭包**是JavaScript中的一个重要概念,它允许函数访问并操作外部作用域中的变量,即使在其外部函数已经执行完毕的情况下。闭包最常见的创建方式就是在函数内部定义另一个函数。例如: ```javascript function box...

    狂神说系列 JavaScript笔记

    【狂神说系列 JavaScript笔记】是一份全面且深入的JavaScript学习资源,旨在帮助开发者和初学者深入理解这门广泛应用于Web开发的脚本语言。这份笔记涵盖了JavaScript的基础语法、核心概念以及高级特性,旨在构建一个...

    JavaScript.The.Good.Parts阅读笔记(二)作用域闭包减缓全局空间污染

    在JavaScript编程中,作用域和闭包是两个非常重要的概念,它们对于理解代码的执行流程以及如何有效地管理变量至关重要。本文将深入探讨这两个主题,并举例说明如何使用它们来避免全局空间污染。 首先,我们来看看...

    Javascript学习笔记.docx

    2. 闭包:闭包是JavaScript中的一个重要特性,它允许一个函数访问并操作其外部函数的作用域内的变量,即使外部函数已经执行完毕。闭包在内存管理中起到关键作用,防止变量被过早回收,常用于实现模块化和数据私有化...

    JavaScript.The.Good.Parts阅读笔记(二)作用域&amp;闭包&amp;减缓全局空间污染

    在探讨JavaScript编程语言时,作用域、闭包和避免全局变量污染是几个非常重要的概念。作用域决定了代码块中变量和其他资源的可见性和生命周期,闭包是JavaScript中一个强大的特性,它允许函数访问并操作函数外部的...

    JavaScript入门课堂随堂笔记.zip

    JavaScript,也被称为JS,是一种广泛应用于网页和网络应用的脚本语言。它是Web开发的核心技术之一,用于...在阅读"JavaScript入门课堂随堂笔记"的过程中,建议结合实际项目进行练习,以便更好地理解和运用所学知识。

    js 笔记 javascript 学习笔记

    本学习笔记将深入探讨JavaScript的核心概念,包括变量、数据类型、操作符、控制流程、函数、对象、数组、原型链、闭包等,并结合实际示例,如my.js、order.js、login.js等文件,来讲解其在实际项目中的应用。...

    javaScript学习笔记.rar

    了解闭包和原型链是深入理解JavaScript的关键,它们对于函数的封装和对象的继承有着重要作用。 接着,要熟悉DOM操作,这是JavaScript与HTML交互的基础。通过DOM,我们可以创建、修改、删除网页元素,实现动态效果。...

    毕设&课设&项目&实训-基于canvas、javascript、bootstrap的读书笔记(共45个demo).zip

    在本项目中,你将深入学习到如何使用canvas、javascript和bootstrap这三种技术来构建一个功能丰富的读书笔记应用。这45个demo涵盖了各种实际应用场景,帮助你掌握这些技术的核心概念和实践技巧。 首先,让我们从...

    前端开发必备JavaScript(含源码课件笔记总结)

    课程中的源码分析部分,可能是对一些经典库或框架的源码解读,如jQuery、lodash等,通过阅读源码,可以深入理解JavaScript的高级技巧和优化手段,提升代码质量。 八、笔记总结 笔记部分是对整个学习过程的记录和...

    李炎恢JavaScript-pdf文档笔记

    《李炎恢JavaScript-pdf文档笔记》是一份详细记录了JavaScript编程语言基础知识至高级应用的教程,涵盖了从第一章到第三十四章的丰富内容。...通过深入阅读和实践,开发者能更好地理解和应用JavaScript的各个层面。

    javascript入门学习笔记

    这份"javascript入门学习笔记"旨在为初学者提供一个全面且深入的JavaScript学习路径。 一、基础语法 JavaScript的基础包括变量、数据类型、操作符、流程控制等。变量用于存储数据,数据类型分为基本类型(如字符串...

    javascript读书笔记

    JavaScript是Web开发中不可或缺的一部分,它是一种轻量级的解释型编程语言,广泛用于网页和网络应用。...继续深入学习,你将掌握更多高级特性,如作用域、闭包、原型链、异步编程等,进一步提升你的JavaScript技能。

    javascript高级编程(学习笔记 包括 1 , 2 版)

    JavaScript 高级编程的学习笔记涵盖了ECMAScript中的基础概念,特别是关于变量、数据类型和运算符的使用。在ECMAScript中,变量可以存储两种基本类型的值:原始值(Primitive Values)和引用值(Reference Values)...

    JavaScript入门课件与笔记

    5. **闭包与作用域**:这是JavaScript中的重要概念,理解它们可以帮助你编写更高效、更易于维护的代码。 6. **原型与继承**:JavaScript的面向对象特性主要通过原型链来实现,理解原型、构造函数、实例、继承等概念...

    javaScript笔记

    这篇笔记将围绕JavaScript的核心概念、语法特点、工具应用等方面进行深入探讨。 一、JavaScript基础 1. 变量与数据类型:JavaScript支持var、let和const声明变量,其中var具有函数作用域,let和const属于块级作用域...

    JavaScript 入门 新手学习笔记

    这篇"JavaScript入门新手学习笔记"提供了全面的学习资源,适合初学者系统性地掌握这一技术。 笔记可能包含了以下关键知识点: 1. **基础语法**:JS的基础包括变量(var、let、const)、数据类型(如字符串、数字、...

Global site tag (gtag.js) - Google Analytics