JavaScript 闭包及其机制

mmsegmentation教程1:自定义数据集、config文件修改、训练教程 mmseg使用教程 阅读详情

首先要区分两个概念,一是匿名函数,一是闭包。

所谓匿名函数,就是创建函数没有给定函数名。经常出现的包括函数表达式,就是定义一个匿名函数,然后将函数赋值给某个变量,而此时这个变量就相当于该函数的函数名,例如:

var sayHi = function(){
    alert("Hi");
};  //注意这个分号
sayHi(); //调用函数
还有一种常用匿名函数的情况是回调函数,如 JQuery 中常用到的:

$("p").click(function(){
    alert("click");
});
此外,还有利用匿名函数作为某函数的返回值:

function sayNameWithAge(age){
    return function(person){
        if(person.age == age){
            return person.name;
        }
    }
}

那么,闭包又是怎么一回事呢?所谓的闭包,其实就是一个函数,而这个函数有一点比较特别,它有权能够去访问其他函数作用域的变量。

从定义中我们发现,其实在上面的匿名函数例子中,就存在这样的闭包。在最后一个例子中,匿名函数访问了函数 sayNameWithAge 的参数 age,那么,这个作为返回值的匿名函数就是一个闭包。

要彻底理解闭包,就必须理解函数调用时的整个机制,这里从作用域链的相关知识来进行讲解。

首先看下面的例子:

function sayName(name){
    alert(name);
}

sayName("Jack");
在上面的函数 sayName 被调用的时候,就会创建一个对应的执行环境和作用域链,如下图所示:

当 sayName 函数被调用时,创建了相应的作用域链,而作用域中包含两个引用分别指向两个对象,其中一个是全局变量对象,这个全局对象是在函数创建的时候就已经创建了,只是在调用函数的时候才将其复制到作用域链中;而另一个就是函数的活动对象,这个对象是在调用函数的时候才创建的。

在函数中访问一个变量时,就会从作用域中搜索对应名字的变量。

而当函数执行完毕后,函数的活动对象会被销毁,而全局变量对象却永远保存在内存中。

但是,上面所说的都是普通函数的情况,对于闭包而言,又是另外一种情况:

以上面的 sayNameWithAge 函数为例:

function sayNameWithAge(age){
    return function(person){
        if(person.age == age){
            return person.name;
        }
    }
}
//创建函数
var sayName = sayNameWithAge(18);
//调用函数
var name = sayName({name:"Jack",age:18});
//解除对匿名函数的引用
sayName = null;
当上面的 sayName 函数被调用的时候,产生的作用域链如下所示:


当匿名函数被 return 后,它的作用域链被创建,并且包含了外部函数的活动对象和全局变量对象,这样一来,这个匿名函数就可以访问 sayNameWithAge 函数中定义的所有变量,也就是一个闭包。

这样的闭包会存在一个问题,就是当 sayNameWithAge 函数执行完毕的时候(JS 的垃圾处理机制大多是标记清除),其活动对象被闭包所引用,所以活动对象并不会被销毁,只有当匿名函数被销毁后,sayNameWithAge 的活动对象才会被销毁,所以上面的最后一行解除对匿名函数的引用不仅是为了销毁闭包的对象,也是为了销毁外部函数的活动对象。所以,慎重使用闭包!!!

关于闭包,还有一个需要注意的地方,就是在闭包中访问其他函数的变量,实际上是因为闭包的作用域链中有指向其他函数的活动对象的引用,而不是闭包自身的活动对象中保存着这些变量。看下面的例子:

function outer(){
    var result = new Array();
    for(var i = 0; i < 5; i ++){
        result[i] = function(){
            return i;
        };
    }
    return result;
}
按照设想,最后 outer 返回的数组各个项中的值应该是与其下标一致的。但是,最后的结果却是每个项的值都是 5

不难想象,在上面的所有闭包的作用域链中,都有一个引用指向了 outer 的活动对象中的参数 i,而且是指向同一个对象。

当 outer 函数执行完毕的时候,i 的值是 5。也就是说,所有闭包中访问 i 的时候取到的值都是 5

那么,我们可以通过另一种方法来实现预想的效果:

function outer(){
    var result = new Array();
    for(var i = 0; i < 5; i ++){
        result[i] = (fuction(index){
            return index;
        })(i);
    }
    return result;
}
这里我们为匿名函数定义一个参数 index,并在每次循环中立即调用该函数,将 i 的当前值复制给参数 index(注意 JS 中是按值传递),并将返回的 index 赋值给 result。

此外,闭包中需要注意的另一个问题是 this 对象。

this 对象在 JS 中是在函数运行时基于函数的执行环境绑定的。而匿名函数的执行环境具有全局性,也就是说,在匿名函数中,this 对象通常指向 window。

var name = "Tom";
var person = {
    name : "Jack",
    sayName : function(){
        return (function(){
            return this.name;
        })();
    }
}
person.sayName(); //Tom
上面在闭包中访问 this.name,其中的 this 对象并非取得自身或是 person 的 this 对象,而是指向 window。

如果需要在闭包中访问外部函数的 this 对象,那么,可以在外部函数中定义一个变量,将 this 对象传给该变量。

var name = "Tom";
var person = {
    name : "Jack",
    sayName : function(){
        var self = this;
        return (function(){
            return self.name;
        })();
    }
}
person.sayName(); //Jack

知识图谱的数据挖掘与分析 1. 背景介绍 1.1 数据挖掘的崛起 随着互联网的普及和大数据技术的发展,数据挖掘已经成为了计算机科学领域的热门研究方向。数据挖掘是从大量的、不完全的、有噪声的、模糊的、随机的实际应用数据中,通过计算机科学、统计学、信息论等多学科交叉的方法,挖掘出有用信息和知识的过程。数据挖掘的目标是从数据中发现有 阅读详情

相关推荐

避坑指南:vue-print-nb打印隐藏元素与空白页的那些事儿

本文深入解析了使用vue-print-nb插件时,打印出现空白页及隐藏元素问题的根本原因与解决方案。核心在于理解浏览器打印原理,并通过CSS媒体查询精准控制样式。文章提供了从重置根元素高度、处理隐藏元素到控制分页的完整避坑指南,帮助开发者彻底解决打印样式难题。

weixin_29008691的博客 436

概念笔记之[javascript<-2->]闭包和封装

闭包简介闭包有很多用法,这种用法(在某个js文件中,把所有的代码括起来)主要目的是对代码进行封装(隔离)。 如果直接使用开放式的写法,在里面定义的变量和函数可能会对全局造成污染,也有可能受到全局定义的变量和函数的污染。 ( 假设: 在你的代码中开放式的(全局)定义了 var abc = 123; function def() { alert('Hello!'); }; 然后在页

架构探险之道 1945

什么是深度展开网络?如何将迭代算法的每一次迭代展开成深度网络对应的一层?深度展开网络进行端对端训练,其中端对端是什么意思?

在深度学习和机器学习的背景下,“端到端”(End-to-end)训练指的是将输入数据直接映射到最终输出的过程,而不需要任何中间的手动数据预处理或特征工程。- **自然语言处理**:端到端自然语言处理系统可以将自然语言输入直接转化为计算机可理解的语言输出,而不需要对语言进行分解和转化。- **推荐系统**:通过使用深度神经网络,端到端推荐系统可以直接根据用户历史行为预测其未来的兴趣爱好,并推荐相应的产品或服务。4. **直接映射**:从输入到输出的直接映射,中间没有任何拆分或分解的过程。

m0_67897882的博客 5432

JS 高级(二)闭包、封装

JavaScript:闭包、封装、封装的三种方式。

商务合作 | 共同学习 | 携手共进 4894

three.js中如何高效加载并播放GLB格式的3D动画

本文详细介绍了在three.js中高效加载并播放GLB格式3D动画的最佳实践。通过对比GLB与GLTF格式的优势,提供从环境搭建、模型加载到动画控制的完整解决方案,并分享性能优化技巧和常见问题排查方法,帮助开发者提升3D动画项目的开发效率和用户体验。

weixin_27890975的博客 362

Mac上Office合法安装与激活全指南:2021/2024/M365区别解析

Office是微软办公套件的核心产品,其在macOS平台的部署逻辑与Windows截然不同——不依赖传统密钥激活,而是基于Microsoft账户与设备标识的云端绑定机制。理解这一原理,是解决‘无法验证开发者’‘打不开’‘功能受限’等常见问题的前提。Office 2021代表永久许可模型,Office 2024 LTSC面向企业离线场景,Microsoft 365则是持续订阅服务,三者在授权验证方式、更新策略与系统兼容性上存在本质差异。实际应用中,需结合macOS版本、芯片架构(Intel/Apple Sil

weixin_33491377的博客 1199

JavaScript中的闭包

JavaScript中的闭包

qq_44482048的博客 6424

告别配置噩梦:用Vcpkg三行命令为Easy3D自动安装Boost、CGAL和Qt(VS2022实测)

本文详细介绍了如何使用Vcpkg工具在VS2022环境下为Easy3D项目一键安装Boost、CGAL和Qt等依赖库,解决传统手动配置的复杂性问题。通过三行简单命令即可自动完成下载、编译和路径配置,大幅提升开发效率,特别适合C++开发者快速搭建3D图形开发环境。

weixin_42525582的博客 210

深入理解js 闭包

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

java_goodstudy的博客 8206

中心对数比变换(Centered Log Ratio Transformation,CLR)的原理及scikit-bio介绍

中心对数比变换(Centered Log Ratio Transformation,CLR)是一种数据预处理方法,常用于成分数据分析领域。在成分数据中,各成分之间通常存在一定的约束关系,比如它们的和为固定值等,中心对数比变换可以有效地处理这种具有特殊约束的数据。官方文档scikit-bio是一个在Python3中处理生物数据的库成分统计 (skbio.stats.composition )模块中的,此函数将组合从Aitchison几何体转换到真实空间。这个clr。

RECORD LEARN PROGRESS 1万+

ssd训练自己的数据集

基于SSD实现目标检测(训练自己的数据集)

reset2021的博客 6803

java script闭包,javascript的闭包和异步机制

javascript的闭包和异步机制javascript的闭包利用了javascript的作用域链和和活动对象(与C/C++这类静态语言不同,有点类似java这种动态语言)。异步机制则是在javascript的运行机制上的编程方式。1、闭包a、活动对象:在一个函数的执行环境中(函数开辟的栈空间)用于存放函数的参数、变量、内部函数。b、实例functioncreateComparisonFunc...

weixin_35439783的博客 238

【数字孪生与仿真技术】14:数据驱动+机理模型:工业级混合建模实战(附MATLAB完整代码+案例解析)

摘要 本文针对工业建模中机理模型精度不足和数据驱动模型缺乏物理约束的痛点,提出混合建模技术作为解决方案。文章系统阐述了混合建模的3种主流架构(参数校正型、残差补偿型、组件替换型),结合清华大学催化裂化装置的实际案例,分析混合建模的工业应用价值。同时以连续搅拌反应釜(CSTR)为例,提供MATLAB环境下残差补偿型混合模型的完整实现代码,详细展示从机理模型构建到数据驱动补偿的全流程,并给出工程实践中的应对策略,为工业建模提供可落地的技术方案。 关键词 混合建模、机理模型、数据驱动、工业建模、MATLAB

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 622

JavaScript闭包(1):闭包的形成机制梳理

JavaScript闭包详解闭包前置知识:作用域,作用域链,变量生命周期1.当我们调用函数的时候,js引擎为我们做了什么?2.JavaScript的垃圾回收机制 闭包前置知识:作用域,作用域链,变量生命周期 从我自学前端以来,就有无数的人告诉我,闭包几乎是JavaScript中最重要的几个技术点之一,必须把把闭包掌握,才算是踏入JavaScript的大门。现在,让我们一起揭开闭包的神秘面纱,看看这到底是个什么机制。 在学习闭包前,我们需要对JavaScript的变量生命周期,作用域,作用域链等有一定的认识,

DDboom的博客 1638

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

javaScript闭包和模块机制

前言: 对于那些有一点Js使用经验但却完全不理解闭包概念的人来说,理解闭包可以看作是某种意义上的重生,但是需要付出非常多的努力和牺牲才能理解这个概念。 一、什么是闭包? 函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在 JavaScript 中,每当函数被创建,就会在函数生成时生成闭包。 二、闭包用途 1、在自身词法作用域之外的地方读取函数内部的变量 2、让这些变量的值始终保持在内存中。不

鸭绒的博客 216

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

JavaScript 闭包与事件轮询机制

闭包(Closure)是能够访问另一个函数作用域中变量的函数。简单来说:当一个内层函数被外层函数返回并在外部调用时,内层函数依然能访问外层函数的局部变量,这就是闭包。自执行函数(Immediately Invoked Function Expression,IIFE)是定义后立即执行的函数创建临时作用域,避免变量污染全局(早期没有let/const时,常用 IIFE 隔离作用域)。为闭包传递参数(如前面的定时器案例)。事件轮询机制。

2301_81157366的博客 696

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【前端】JavaScript中的闭包与垃圾回收机制详解

在 JavaScript 编程范畴内,垃圾回收机制(GC)与闭包是两个高度复杂且具关键意义的概念。这些机制直接影响内存管理和状态维护,构成了现代 JavaScript 编程的重要理论基础。为了帮助深入理解这些机制的核心原理和实际应用,本文将通过系统化的理论阐述和详细的代码示例展示它们在不同场景中的表现及潜在挑战。 2024.12.11-✍22min

禅宗里有一个词叫做“因缘和合”。 所谓因缘,是指事件要发生所必须的条件。因缘和合就是当你聚集了这件事的一切条件,它就会自然而然的发生。“它就会自然而然的发生”,这种朴素而坚定的价值观让我们感到无比安心,安心到可以不用有任何担心焦虑。 1482

javascript的闭包机制

闭包产生的条件 当内部函数被保存到外部,就会产生闭包。闭包会导致原有作用域链不释放,造成内存泄露。 详细点:闭包是在函数被调用时才被创建,与作用域链的访问顺序有关,只有内部函数访问上层作用域链的变量对象时,才会形成闭包。 例子 function test(){ var arr = []; for(var i = 0; i < 10; i++){ ...

qq_41938120的博客 1728

Javascript闭包机制

原文地址:http://www.felixwoo.com/archives/247 参考:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html 最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业。对于初学者来说别说理解闭包了,就连文字叙述都很难看

wusuopuBUPT的专栏 1105

深入了解JavaScript的闭包机制

这篇文章主要介绍了JavaScript的闭包机制,针对内嵌函数的变量访问等问题分析了JS的闭包,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。 JavaScript 变量可以是局部变量或全局变量。 私有变量可以用到闭包。 全局变量 函数可以访问是有函数内部定义的变量,如: 实例 function myFunction() { var a ...

weixin_44526331的博客 169

javascript闭包机制及说明

javascript闭包机制及说明 老狼 post in [JAVASCRIPT] 2008-4-8 8:54 Tuesday 本文结合 ECMA 262 规范详解了闭包的内部工作机制,让 JavaScript 编程人员对闭包的理解从“嵌套的函数”深入到“标识符解

lionzl的专栏 648

闭包js运行机制

2.在作用域链中,该函数处于作用域第一层该函数的外部函数的作用域处于第二位,外部的外部处于第三位,直到作用域的终点为全局环境,函数本身处于最底层的作用域链。作用域链1.当某个函数被调用时会创建一个执行环境和一个作用域链,同时初始化活动对象。(3)f2在f1函数的作用域中声明,在全局作用域中被调用,f2就是闭包。[2]闭包结构当外部函数被调用之后,闭包结构依然被保留在系统中。---指在函数声明时的作用域以外的地方被调用的函数。---即范文上层函数的作用域的内层函数就是闭包。...

weixin_47764323的博客 191

JavaScript闭包的底层运行机制

我研究JavaScript闭包(closure)已经有一段时间了。我之前只是学会了如何使用它们,而没有透彻地了解它们具体是如何运作的。那么,究竟什么是闭包? Wikipedia给出的解释并没有太大的帮助。闭包是什么时候被创建的,什么时候被销毁的?具体的实现又是怎么样的? “use strict”; var myClosure = (function outerFunction() { var hi...

weixin_45556713的博客 200

04期:从JS垃圾回收机制和词源来透视闭包

深入底层(函数的解析和执行过程、JS变量查找机制和JS垃圾回收机制),从里子讲闭包,从词源讲闭包,帮助各位同学理解、会用和用好闭包。

cai649399010的专栏 602

深入解析JavaScript解析机制与闭包原理实例

篇文章主要介绍了JavaScript解析机制与闭包原理,结合实例形式详细分析了javascript解析机制相关概念、功能、用法以及闭包的原理、定义、使用方法,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。 js解析机制: js代码解析之前会创建一个如下的词法环境对象(仓库):LexicalEnvironment{ } 在扫描js代码时会把: ...

weixin_44526331的博客 207

js执行机制,三、作用域链和闭包(clousre)

对作用域链和词法作用域的解释,和形成的闭包(closure)及闭包的使用

李三岁的博客 1188
上一篇: 解析Javascript事件冒泡机制
下一篇: 【BOM操作】JavaScript中的event对象之总结
leadn
博客等级 码龄10年 13粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值