关于Javascript闭包的理解

以下内容属个人理解,如有看不明白或漏洞之处,纯属水平不佳,还望见谅。

关于闭包,高程里的定义是:指有权访问另一个函数作用域中的变量的函数。创建闭包最常见的方法就是在一个函数的内部再创建一个函数。

这里先创建一个函数f

function f(v1, v2) {

// 函数表达式

}

并进行调用

let result = f(5, 10)

为了搞懂闭包,首先要明白上面程序整个过程中发生了什么:

1.当调用f()函数的时候,后台创建了一个f()的执行环境与相应的作用域链(这里的作用域链的来源:在创建f()函数的时候,会创建一个预先包含了全局变量对象的作用域链,并

保存在内部的[[Scope]]属性中,当调用f()函数时,会先创建执行环境,然后通过复制[[Scope]]中的作用域链来构建自己的作用域链

2.使用arguments和其他被命名的参数的值来初始化f()的活动对象(这里的活动对象将会被推入作用域的前端,全局变量对象始终位于最后一位,外部函数的活动对象始终位于第二位,外部函数的外部函数的活动对象始终位于第三位...以此类推,在f()函数的作用域链中包含两个变量对象:本地活动对象和全局变量对象(这里还要注意,全局变量对象是始终存在的,而本地活动对象只有在函数调用的时候才存在,同时作用域链中,仅仅是对对象的引用,而非真的包含这些对象)

3.函数调用结束后,执行环境和作用域链被销毁。

明白过程中后,我们再来看何谓闭包

这里创建一个函数f1,并在其内部返回一个匿名函数

function f1 (v1) {

  return functiono (v2, v3) {

    let o1 = v2 * v1

    let o2 = v3 * v1

    return o1 + o2

  }

}

let sum = f1(5)

let result = sum(2, 3)

sum = null // 解除对匿名函数的引用,释放内存

在上述代码执行后,产生的执行环境和作用域链的关系如下图所示

(这里因为手残画图太丑,就用高程里的这张图代替...将createComparisonFunction当作f1就可以,其余变量自行脑部替换)

在 let sum = f1(5)这里,匿名函数从f1中被返回,其作用域链中包含了本地活动对象,f1的活动对象以及全局变量对象,在f1执行完毕后,执行环境被销毁,但其活动对象却不会被销毁,因为在f1返回的匿名函数的作用域链中,依旧保持着对f1活动对象的引用,只有当匿名函数也销毁了以后,才能真正的销毁所有的活动对象。

由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多,我们建议读者只在绝对必要时再考虑使用闭包。虽然像V8 等优化后的JavaScript 引擎会尝试回收被闭包占用的内存,但请大家还是要慎重使用闭包。

原文地址:https://www.cnblogs.com/simple-yu/p/12259114.html

时间: 2024-07-30 21:17:57

关于Javascript闭包的理解的相关文章

javascript闭包的理解-韩烨

javascript闭包是javascript的难点,很多人对js闭包不是很理解,我对js闭包一开始也是云里雾里,我刚刚进兴安得力的时候,做的转正试题中就有一个对闭包理解的题目.如何理解javascript的闭包呢?下面我们一起来学习一下: 闭包的含义和理解 通俗地讲,JavaScript 中每个的函数都是一个闭包,但通常意义上嵌套的函数更能够体现出闭包的特性,请看下面这个例子: var generateClosure = function() { var count = 0; var get

javascript 闭包的理解

看过很多谈如何理解闭包的方法,但大多数文章,都是照抄或者解释<Javascript高级程序设计(第三版)>对于闭包的讲解,甚至例程都不约而同的引用高程三181页‘闭包与变量’一节的那个“返回数组各个项,结果各个项的值都相同”的例程,还有些文章的讲解过程上一步与下一步之间的跨度简直就是一步登天,让人反复看半天都无法理解. 闭包的理解需要很多概念做铺垫,包括变量作用域链.执行环境.变量活动对象.引用式垃圾内存收集机制等,如果对本文涉及的这些概念不理解,可以去找本<Javascript高级程序

我对JavaScript闭包的理解

一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数

javascript闭包的理解和实例

所谓闭包,值得是词法表示包括不必要计算的变量的函数,也就是说,该函数可以使用函数外定义的变量. 顺便提示一下: 词法作用域:变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通过静态分析就能确定,因此词法作用域也叫做静态作用域. with和eval除外,所以只能说JS的作用域机制非常接近词法作用域(Lexical scope). 下面是一个简单的使用全局变量的闭包实例: 1 var sWord="Hello,Welcome to web前端开发工程师的博客,请多多指教.&

javascript闭包的理解

闭包,是javascript中独有的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述. 1 初探 在接触一个新技术的时候,我首先会做的一件事就是:找它的demo code.对于码农们来说,代码有时候比自然语言更能理解一个事物. 其实,闭包无处不在,比如:jQuery.zepto的主要代码都包含在一个大的闭包中,所以下面我先写一个最简单最原始的闭包demo,好让你在大脑里 产生闭包的画面

Javascript闭包简单理解

提到闭包,想必大家都早有耳闻,下面说下我的简单理解.说实话平时工作中实际手动写闭包的场景并不多,但是项目中用到的第三方框架和组件或多或少用到了闭包.所以,了解闭包是非常必要的.呵呵... 一.什么是闭包简而言之,就是能够读取其他函数内部变量的函数.由于JS变量作用域的特性,外部不能访问内部变量,内部可以外部变量. 二.使用场景1. 实现私有成员.2. 保护命名空间,避免污染全局变量.3. 缓存变量. 先看一个封装的例子: var person = function () { // 变量作用域为函

javascript 闭包的理解(二)

// 定义一个User构造函数 function User(properties){ //遍历对象属性,确保它作用域正确 for(var i in properties){ (function(which){ var p = i; //为属性创建获取器 which["get"+i] = function(){ return properties[p]; }; //为属性创建设置器 which["set"+i] = function(val){ properties[

深入理解javascript闭包

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function

全面理解Javascript闭包和闭包的几种写法及用途

一.什么是闭包和闭包的几种写法和用法                                                       1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态. 2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区. 简单的说,Javascript允许使用内部函数---即函数定义和函数表