闭包 私有变量

实战指南:基于Windows Server构建企业级AAA认证体系 本文详细介绍了如何在Windows Server环境下构建企业级AAA认证体系,涵盖AD域服务部署、NPS服务器配置及华为设备对接实战。通过整合Radius协议与AD域账号管理,实现网络设备的统一认证与权限控制,提升企业IT安全管理效率。特别适用于需要零成本实现AAA认证的中大型企业。 阅读详情

 转自:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }   
})();

console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */

 

在循环中创建闭包:一个常见错误节

在 ECMAScript 2015 引入 let 关键字 之前,在循环中有一个常见的闭包创建问题。参考下面的示例:

<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email"></p>
<p>Name: <input type="text" id="name" name="name"></p>
<p>Age: <input type="text" id="age" name="age"></p>
function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      showHelp(item.help);
    }
  }
}

setupHelp();

 

数组 helpText 中定义了三个有用的提示信息,每一个都关联于对应的文档中的input 的 ID。通过循环这三项定义,依次为相应input添加了一个 onfocus  事件处理函数,以便显示帮助信息。

运行这段代码后,您会发现它没有达到想要的效果。无论焦点在哪个input上,显示的都是关于年龄的信息。

原因是赋值给 onfocus 的是闭包。这些闭包是由他们的函数定义和在 setupHelp 作用域中捕获的环境所组成的。这三个闭包在循环中被创建,但他们共享了同一个词法作用域,在这个作用域中存在一个变量item。当onfocus的回调执行时,item.help的值被决定。由于循环在事件触发之前早已执行完毕,变量对象item(被三个闭包所共享)已经指向了helpText的最后一项。

解决这个问题的一种方案是使用更多的闭包:特别是使用前面所述的函数工厂:

function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function makeHelpCallback(help) {
  return function() {
    showHelp(help);
  };
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
  }
}

setupHelp();

 

这段代码可以如我们所期望的那样工作。所有的回调不再共享同一个环境, makeHelpCallback 函数为每一个回调创建一个新的词法环境。在这些环境中,help 指向 helpText 数组中对应的字符串。

另一种方法使用了匿名闭包:

function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    (function() {
       var item = helpText[i];
       document.getElementById(item.id).onfocus = function() {
         showHelp(item.help);
       }
    })(); // 马上把当前循环项的item与事件回调相关联起来
  }
}

setupHelp();

避免使用过多的闭包,可以用let关键词:

function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}

function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];

  for (var i = 0; i < helpText.length; i++) {
    let item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      showHelp(item.help);
    }
  }
}

setupHelp();

这个例子使用let而不是var,因此每个闭包都绑定了块作用域的变量,这意味着不再需要额外的闭包。

性能考量节

如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。

例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。原因是这将导致每次构造器被调用时,方法都会被重新赋值一次(也就是,每个对象的创建)。

考虑以下示例:

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}

在上面的代码中,我们并没有利用到闭包的好处,因此可以避免使用闭包。修改成如下:

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype = {
  getName: function() {
    return this.name;
  },
  getMessage: function() {
    return this.message;
  }
};

但我们不建议重新定义原型。可改成如下例子:

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};

在前面的两个示例中,继承的原型可以为所有对象共享,不必在每一次创建对象时定义方法。参见 对象模型的细节 一章可以了解更为详细的信息。

【数据集实例】CMIP6气候模式数据下载-以河东地区为例 以河东地区为例,介绍CMIP6数据下载及处理 阅读详情

相关推荐

ADS RFpro 射频阻抗仿真步骤

导入器件后,在库里面选取器件的对应模型,如图所示我们选取10pf 系统自带的村田模型。选取网络上的器件,拖入到下面component Models。导入成功后,截取需要仿真的区域(不截取仿真时间会非常长),可以生成对应如下原理图,通过原理图继续调整仿真。图上找到需要仿真链路上的网络,右键设置为信号。的叠层信息,按照PCB板厂提供信息填写完整。选择仿真的频率范围和频点数,生成如下图的RFPro仿真界。,然后再把GND也添加到下面。按图设置截取需要仿真的部分。添加成功后 网络就有了,15 双击run开始仿真。

m0_72954480的博客 3217

JS中函数(三)(闭包、IIFE、私有变量等)

JS中函数(三)(闭包????IIFE????私有变量等)   这是 JS 函数章节中的第三部分类容,也是最后一部分,最重要的一部分内容,其中的闭包无论在面试过程中还是理解 JS 其他重要知识点中都尤为重要。本部分除了闭包,还讲到立即执行函数,私有变量,静态私有变量,模块模式及模块增强模式。 10.14、闭包   闭包指的是那些引用了另一个函数作用域中变量的函数,闭包让你可以在一个内层函数中访问到其外层函数的作用域。通常是在嵌套函数中实现的。比如前文中写过的 createComparisonFunction

ItDaChuang的博客 808

android 运动目标检测_MindSpore应用案例:AI对篮球运动员目标的检测

MindSpore作为一个端边云协同的开源的全场景AI框架,今年3月份开源以来,受到了业界的广泛关注和应用,欢迎大家参与开源贡献、模型众智合作、行业创新与应用、学术合作等,贡献您在云侧、端侧 (HiMindSpore 应用程序)、边侧以及安全领域的应用案例。MindSpore与您在AI领域共同成长,让AI使能千行百业,释放出强大的生产力。本文讲述的是MindSpore对篮球运动员目标的检测应用,通...

weixin_33603813的博客 835

JavaScript 闭包

本地全局闭包。

weixin_53526046的博客 1162

Protege新手必看:从安装到建模的完整指南(附推理功能详解)

本文为Protege新手提供从安装、配置到核心建模的完整实战指南。详细讲解了Java环境准备、本体项目创建、类与属性定义、个体填充等关键步骤,并重点解析了推理功能的配置与使用,帮助读者快速构建可逻辑推理的知识图谱,避开常见陷阱。

numpy6sculptor的博客 797

深入博通PEX89000内部:那颗ARM CPU和Synthetic Mode到底能玩出什么花样?

本文深入解析博通PEX89000系列PCIe交换芯片内置的ARM CPU与Synthetic Mode技术,揭示其在AI计算和数据中心的智能潜能。通过ARM Cortex CPU的实时控制和Synthetic Mode的自治网络功能,PEX89000实现了GPU集群的动态拓扑重组和资源池化,大幅提升AI训练效率。文章还探讨了该技术在软件定义数据平面和弹性AI架构中的创新应用。

weixin_30776273的博客 212

闭包简单理解

当内部函数引用外部函数的变量时,会从当前作用域开始向上查找,直到找到该变量为止。闭包的主要特点是内部函数可以访问外部函数的变量和参数,而这些变量和参数对于外部函数来说是私有的,不会被其他函数所访问。需要注意的是,如果闭包中引用了一个对象或数组,并且在内部函数中修改了该对象或数组的属性,那么外部函数也会受到影响,因为闭包和外部函数共享同一个对象或数组。闭包是指在一个函数内部创建另一个函数,并且该内部函数可以访问外部函数的变量和参数,即使外部函数已经执行完毕并返回了,内部函数仍然可以访问这些变量和参数。

xy1580的博客 270

车辆网络安全ISO/SAE 21434解读(一)概述

ISO/SAE 21434 《道路车辆 网络安全工程》是SAE和ISO共同制定的一项针对道路车辆的网络安全标准,它是一个面向汽车行业全供应链(OEM及各级供应商)的车辆网络安全管理指导文件

xiaoxiabang的博客 8426

js必须了解的闭包私有化变量原理

//闭包的私有化变量 function Person() { /* var this = { makeMoney : function () {}, offer : function () {} } 此时的Person里面只有两个方法, 如果想通过Person访问money是访问不到的, 如果你想通过方法调用来访问(Perso...

丰柏林的博客 1549

PINNACLE:PINN自适应配点与实验点选择算法

PINNACLE算法通过引入动态权重机制,实现了PINN训练点选择的自适应优化。该算法基于对训练过程中不同区域学习需求变化的深入理解,设计了平滑过渡的权重函数,确保了模型在不同训练阶段能够优先学习最需要的区域。理论分析和实验结果均表明,PINNACLE不仅能够保证收敛性,而且能够显著提高PINN的性能。这一算法为物理信息神经网络的应用提供了重要支持,尤其适用于复杂PDE问题的求解。

VectorShift的博客 1137

单反相机物镜设计[DG-10]

REAR(要打在像面,操作数要找像面对应位置15):以透镜单位表示的真实光线径向坐标,波长由Wave定义,参见“Hx、Hy、Px和Py”。最小玻璃厚度最小不能小于semi-dia的1/10,要根据layout看有没有过厚过薄,反复调节。PROD:两个操作数的乘积(操作#1 X操作#2)。3x4就是57.3x0.41=23.5。拦光一般在第一面和最后一面操作,减少边缘无用光线。光阑面与镜面贴近,要调距离,同时设置光阑像差。后截距是指从镜头后表面到焦点的距离。CONS:弧度转为角度。镜头相互嵌入,有错误。

weixin_72050316的博客 600

如何用闭包实现一个私有变量?给出代码示例。

通过闭包实现私有变量是 JavaScript 中经典的封装模式,广泛应用于模块化开发和库/框架设计中(如 Redux 的 Store 封装)。实现私有变量,利用函数作用域封装数据,并通过暴露的方法控制访问。在 JavaScript 中,可以通过。

qq_44165941的博客 339

ABAP CURR Data Type 深度解析与实战案例

CURR 数据类型是 SAP ABAP 中为处理货币金额而设计的一种特殊数据类型。CURR 数据类型能够自动根据关联的货币代码字段(例如 WAERS)确定小数位数,从而保证金额数据的精度与正确性。CURR 类型通常在 SAP 数据字典中使用,常见于各类业务数据表中,如会计凭证、销售订单等场景中,用于存储货币金额。CURR 数据类型底层实现上类似于 DEC 数据类型,但其特别之处在于与货币代码字段的绑定,这使得金额的格式化和显示可以自动匹配相应的货币规则。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 878

JS闭包 与 静态私有变量

JS 静态私有变量 近期因为面试原因,又重新复习了一下闭包,于是逛了各大社区,看了各种JS书籍对闭包的定义和举例,这过程中发现一个很有意思的东西:静态私有变量,所以在这里把一些心得和总结和大家分享一下,下面直接上代码 var Person = (function (){ // 静态私有变量 var num = 0 // 静态私有方法 function() { // ....

weixin_34403976的博客 899

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

闭包与私有变量

1.闭包是为了创建私有变量而生的一种技术,该技术采用了外层包裹一层函数;(但不是创建私有变量的唯一技术) 2. 未包裹外层闭包函数时,申明的变量是公用变量,大家都可以访问和修改; var num = 10 function fun() { console.log(num) //10 } fun() num += 10 console.log(num) //20 外层包裹一层函数之后,外部函数无法访问和修改该变量; function fn() { var num = 10 function fun()

SavaMatrix的博客 458

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

闭包产生私有化变量,防止命名空间的污染

<script> /*下面三个函数分别和Deng形成了闭包,共同用Deng的闭包 PrepareWife这个变量能用,但是无法访问,因为它不是对象生成的东西,是对象和原有空间生成的闭包,这就是私有化变量 */ function Deng(name,wife){ var prepareWife="xiaozhang"; this.name=name; this.wife=wife; this.divorce=function()

x1037490413的博客 381

从JavaScript内存回收看为什么闭包可以实现私有变量

文章目录回顾闭包词法作用域(静态作用域)和动态作用域垃圾回收 ♻️现在再来看为什么使用闭包可以定义私有变量 回顾闭包 关于闭包这篇详细写过:JavaScript 闭包 先来看个闭包的 ???? function f1() { var n = 0; // n是f1函数的局部变量 function f2() { // f2是f1函数的内部函数,是闭包 n += 1; // 内部函数f2中使用了外部函数f1中的变量n console.log(n);

Amy的博客 542

Js 使用闭包(closure)定义私有变量

Js中的内部函数可以访问外部函数的变量,称之为闭包 作用:私有变量 function privateVariable() { var value; this.setValue = function(value) { value= value; }; this.getValue = function() { return va...

Fanstasic的博客 1000

使用闭包封装私有变量

使用闭包封装私有变量 这种方法把一些变量封装在闭包的内部,只暴露一些接口跟外界通信: var user = (function(){ var __name = 'sven', __age = 29; return { getUserInfo: function(){ return __name + '-' + __age; } } })(); alert(user.getUserInfo()

cyyax的博客 1143

【JS】JavaScript闭包(私有变量,局部变量)

【代码】【JS】JavaScript闭包。

-凌凌漆-的博客 484

Python中巧用闭包实现私有变量封装

闭包是指在一个内部函数中引用外部函数的变量,即使外部函数已经执行完毕,这些变量仍然可以被内部函数访问。通过闭包实现私有变量封装是Python中一种优雅的编程技巧,它提供了良好的封装性同时保持了代码的简洁性。print(get_cache('user_1')) # 输出: {'name': 'Alice', 'age': 30}print(person.display_info()) # 输出: 姓名: 张三, 年龄: 25。1. 真正的数据隐藏:外部无法直接访问闭包内的变量。

AoGNAEYT的博客 585

闭包模拟静态变量与私有变量

模拟静态变量 let Counter = (function () { // 闭包上下文 let COUNTER = 0 function changeBy (val) { COUNTER+=val } function Counter () {} Counter.prototype.increment = function () { changeBy(1)...

weixin_33895016的博客 192

4.0 利用闭包创建私有变量

通常,JavaScript 开发者使用下划线作为私有变量的前缀。但是实际上,这些变量依然可以被访问和修改,并非真正的私有变量。这时,使用闭包可以定义真正的私有变量: function Product() { var name; this.setName = function(value) { name = value; }; this.getName = function() { return name; }; } var p =

AndrewNeo 704

利用闭包私有化变量

利用闭包私有化变量 function Student(name, grade){ var fakergrade = 100; this.name = name; this.grade = grade; this.cheat = function(){ this.grade = fakergrade; } this.sayfakegrade = function(){ console...

qq_43618136的博客 287

关于私用变量在JavaScript 闭包中的注意(私有变量可以用到闭包)

JavaScript私有变量可以用到闭包。 参考https://www.runoob.com/js/js-function-closures.html 注意下例中计数结果为3: var add = (function () { var counter = 0; return function () {return counter += 1;}//返回方法引用 })()...

carcarrot的博客 212

闭包作用:私有化变量

function Liu(name,wife){ var preWife = "xiaozhang"; this.name = name; this.wife = wife; this.divorce = function(){ this.wife = preWife } this.changePreWife = function(t

mike_95的博客 594

JavaScript闭包与私有变量

function Person(name) { /** * 此时就没有办法直接访问name这个属性,因为没有this.name * 要访问name只能通过this.getName和this.setName * 但是使用这种方式创建私有变量带来的问题是,每个对象都存储大量

zhuhai__yizhi的专栏 1251
上一篇: js 通知
下一篇: 报文 内存分配
Bill11YAng
博客等级 码龄14年 165粉丝 230原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值