JavaScript 闭包及其机制

TensorFlow_PyTorch实战:构建AI人工智能回归模型 回归分析是机器学习的核心任务之一,用于预测连续型目标变量(如房价、股票价格、用户留存时间等)。基础线性回归模型的数学原理与代码实现多项式回归模型的过拟合处理与正则化技巧自定义数据集加载与数据预处理流程动态图(PyTorch)与静态图(TensorFlow)的编程范式对比模型评估指标与可视化分析方法核心概念:对比两大框架的架构设计,解析回归模型核心组件数学原理:推导线性回归的假设函数、损失函数及优化算法算法实现:提供TensorFlow和PyTorch的完整代码示例项目实战。 阅读详情

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

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

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

YOLOv8改进:卷积篇 | 保姆级探索动态蛇形卷积 (Dynamic Snake Convolution) 的实现与应用 动态蛇形卷积是一种新的卷积操作,它能够更好地捕捉图像中的细节信息。传统卷积核的形状和大小是固定的,而动态蛇形卷积则允许卷积核在不同的位置动态调整其形状,以更好地适应输入数据的特点。这种灵活性使得动态蛇形卷积在处理复杂背景和细节丰富的图像时具有显著优势。我们先定义一个基本的动态蛇形卷积模块。这个模块将作为YOLOv8卷积层的替代。为了全面集成动态蛇形卷积,我们需要修改YOLOv8的模型定义,将所有的基础卷积层替换为我们的SnakeConv模块。 阅读详情

相关推荐

视觉辅助RIS波束追踪:用摄像头“看见”用户,实现毫秒级波束对准

在无线通信领域,波束成形技术是提升高频段信号覆盖与质量的核心手段,其原理是通过调整天线阵列的相位,使信号能量在特定方向相干叠加,形成高增益定向波束。这项技术的价值在于能有效克服高频信号路径损耗大、穿透性差的瓶颈,广泛应用于5G/6G、毫米波通信及室内定位等场景。然而,传统波束追踪依赖信道估计或波束扫描,存在训练开销大、实时性差的问题。本文聚焦于一种创新解决方案:将计算机视觉与可重构智能表面(RIS)相结合。通过摄像头直接感知用户位置,并利用RIS快速重构反射波束方向,实现了近乎零开销、毫秒级延迟的波束追踪,

weixin_33552698的博客 620

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

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

架构探险之道 1945

逆变器方案(工频全套)工频正弦波逆变器开发板全套设计资

逆变器方案(工频全套)工频正弦波逆变器开发板,24V-72V通用12只TO-247封装MOS管,额定输出功率6500W以下;配有触摸屏操作界面,运行数据一目了然,带市电互补UPS功能,可选择电池优先或市电有限工作,我们的开发板均从实战角度出发,让您的学习更便捷,包含全套设计资料,PCB.原理图.源代码,程序均有中文注释,MCU选用美国微芯公的PIC-8位单片机,民用数字电源首选单片机,抗干扰能力强,运行稳定。...

m0_73494033的博客 891

JS 高级(二)闭包、封装

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

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

Amesim与Simulink联合仿真:S-Function接口配置与实战避坑指南

本文详细介绍了Amesim与Simulink联合仿真中S-Function接口的配置方法与实战避坑指南。从环境搭建、编译器配置到S-Function接口实战,逐步解析关键步骤与常见问题解决方案,帮助工程师高效实现多领域系统仿真,特别适合汽车、航空航天等复杂系统建模场景。

weixin_29173777的博客 344

一文读懂“数据分发服务DDS”(Data Distribution Service,RTPS,OMG)

DDS 数据分发服务(Data Distribution Service) 数据分发服务DDS(DataDistributionService)是对象管理组织(OMG)在HLA及CORBA等标准的基础上制定的新一代分布式实时通信中间件技术规范,DDS采用发布/订阅体系架构,强调以数据为中心,提供丰富的QoS服务质量策略,能保障数据进行实时、高效、灵活地分发,可满足各种分布式实时通信应用需求。DDS...

DDS技术交流推广大本营 4万+

JavaScript中的闭包

JavaScript中的闭包

qq_44482048的博客 6424

美团外卖 mtgsig 1.2 逆向工程与补环境实战指南

本文深入解析了美团外卖核心风控参数mtgsig 1.2的生成机制与逆向实战。通过拆解其复杂的JSON结构,揭示了设备指纹、环境信息加密等关键字段。重点阐述了在Node.js中模拟浏览器环境(补环境)的核心方法,包括DOM/BOM对象、本地存储及Canvas/WebGL等高级指纹的模拟技巧,为安全研究和合规自动化测试提供了一套完整的技术指南。

uber9的博客 409

深入理解js 闭包

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

java_goodstudy的博客 8206

量化回测框架三选一:Backtrader、Zipline、PyAlgoTrade,新手到底该跟谁学?

本文对比分析了三大量化回测框架Backtrader、Zipline和PyAlgoTrade,帮助新手选择最适合的入门工具。从安装配置、策略编写到文档查阅,详细解析各框架的特点和适用场景,为量化交易初学者提供实用指南。

weixin_28745309的博客 267

后悔没早点知道!用AI只需四步,一次性讲清高质量论文引言写法(附公式+AI指令)

帮我写SCI 论文撰写引言的“研究背景与重要性”,要求从本研究所属领域的小背景切入,使用现在时态描述该领域的总体状况与发展趋势,突出其在学术研究、实际应用或社会层面的重要价值,并通过一个吸引人的钩子开头,如关键事实、现实问题或学术热点,引导读者关注本主题的重要性。梳理你所在领域和你研究相关的关键成果,但不能罗列所有文献,重点抓核心脉络,这部分最重要的实际上是让你了解别人的研究脉络,然后在每个关键的节点上,引用几篇关键参考文献作支撑,来体现你对领域的熟悉度就可以了。3)研究缺口模糊,没法突出问题的真实价值;

qq_64378896的博客 116

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

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

weixin_35439783的博客 238

UE4打包为Framework库嵌入iOS原生工程

UE4打包为Framework库嵌入iOS原生工程

tangfuling1991的博客 1294

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

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

DDboom的博客 1638

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

javaScript闭包和模块机制

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

鸭绒的博客 216

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

JavaScript 闭包与事件轮询机制

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

2301_81157366的博客 696

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

【前端】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、付费专栏及课程。

余额充值