js闭包的作用和应用的学习

2023-05-16

什么是闭包

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包closure

闭包的应用

 因为它允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。

词法作用域

MDN例子

function init() {
    var name = "Mozilla"; // name 是一个被 init 创建的局部变量
    function displayName() { // displayName() 是内部函数,一个闭包
        alert(name); // 使用了父函数中声明的变量
    }
    displayName();
}
init();

init() 创建了一个局部变量 name 和一个名为 displayName() 的函数。displayName() 是定义在 init() 里的内部函数,并且仅在 init() 函数体内可用。请注意,displayName() 没有自己的局部变量。然而,因为它可以访问到外部函数的变量,所以 displayName() 可以使用父函数 init() 中声明的变量 name 。

使用这个 JSFiddle 链接运行该代码后发现, displayName() 函数内的 alert() 语句成功显示出了变量 name 的值(该变量在其父函数中声明)。这个词法作用域的例子描述了分析器如何在函数嵌套的情况下解析变量名。词法(lexical)一词指的是,词法作用域根据源代码中声明变量的位置来确定该变量在何处可用。嵌套函数可访问声明于它们外部作用域的变量

应用

1. 函数柯里化的应用

个人认为最好的应用

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

在这个示例中,我们定义了 makeAdder(x) 函数,它接受一个参数 x ,并返回一个新的函数。返回的函数接受一个参数 y,并返回x+y的值。

从本质上讲,makeAdder 是一个函数工厂 — 他创建了将指定的值和它的参数相加求和的函数。在上面的示例中,我们使用函数工厂创建了两个新函数 — 一个将其参数和 5 求和,另一个和 10 求和。

add5 和 add10 都是闭包。它们共享相同的函数定义,但是保存了不同的词法环境。在 add5 的环境中,x 为 5。而在 add10 中,x 则为 10。

2. 模拟私有属性,方法

不好,建议将其放在原型上面

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

var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */

请注意两个计数器 Counter1 和 Counter2 是如何维护它们各自的独立性的。每个闭包都是引用自己词法作用域内的变量 privateCounter 。

每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境。然而在一个闭包内对变量的修改,不会影响到另外一个闭包中的变量。

性能考虑

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

例子

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;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

js闭包的作用和应用的学习 的相关文章

  • 利用margin来实现两端对起

    为什么会对齐一般我们给li标签设置margin left最后一个总是会有一个不需要的left那为什么如何去除呢 xff1f 答案是 xff1a margin xff1a 负值 如果ul右边多了20px xff0c 那么给ul设置个margi
  • 裸机通过u盘以hostengine的方式成功安装ovirt4.5

    本次安装是在两台服务器上进行 xff0c 采用hostengine的方式安装 xff0c 也就是一台机上先安装oVirt node xff0c 再安装oVirt engine xff0c 另外一台机安装oVirt node xff0c 并加
  • 关于paddin-bottom的中的未定义的问题

    css世界的学习后 xff1a padding的兼容问题一般遇不到 xff0c 滚轮什么时候出现 xff1a Chrome浏览器的滚轮是在子元素超过content box的时候显示 xff1b IE Firefox是在超过padding b
  • 流动性的深入学习

    何为 34 流 34 流 61 文档流 xff1b 当我们在一个容器中倒入足量的水时 xff0c 水一定会均匀平铺整个容器 所以流动性也就是100 自适应 但width 61 100 xff01 61 流动性自适应100 原因 xff1a
  • 如何用border来画三角形

    学习总结 HTML lt div class 61 34 son 34 gt lt div gt CSS son width 0px border 20px solid border color black transparent tran
  • window和document的区别

    window对象 它是一个顶层对象 而不是另一个对象的属性 xff0c 即浏览器的窗口 document 当前显示的文档 该属性本身也是一个对象
  • JS距离的理解

    偏移量 offsetWidth 元素在水平方向上占用的空间大 xff0c 包括元素的宽度 可见的垂直滚动条宽度 左边框高度和右边框高度 offsetWidth 61 width 43 padding 43 border offsetHeig
  • 汉堡按钮的制作以及其中的问题

    第一种自己写的 xff0c 下面的第二种是网上的用一个span使用做出来的 HTML lt div class 61 34 box 34 gt lt chang用来判断是否变换 gt lt span class 61 34 s1 34 gt
  • 对js动画和时间控制的使用

    JavaScript Document 打算移动的元素ID xff1b elementID 该元素的目的地的 34 左 34 位置 xff1b final x 该元素的目的地的 34 上 34 位置 xff1b final y 停顿时间 x
  • css动画小结

    一 转换 transform IE9 43 1 旋转rotate transform rotate 30deg ms transform rotate 30deg IE 9 webkit transform rotate 30deg Saf
  • Django 判断访问来源是PC端还是手机端

    pc or mobile py 判断访问来源是pc端还是手机端 import re def judge pc or mobile ua 34 34 34 param ua 访问来源头信息中的User Agent字段内容 return 34
  • 圆形进度条是学习

    学习网站 xff1a http www cnblogs com jr1993 p 4677921 html CSS margin 0px padding 0px box margin 50px auto 0 width 300px heig
  • 定位插件

    写了个等位插件 xff0c 点击nav中的LI xff0c 位移 xff08 与href有视觉效果 xff09 到达相应板块 xff08 这里的类比li中的类中多了个H字母 xff09 的位置 lt li class 61 34 wz 34
  • JQ复习

    一选择器 1 基本选择器 2 层级选择器 3 过滤选择器 first 选取第一个元素 last 选择最后一个元素 not 去除所有与给定选择器匹配的元素 39 input not first 39 even选取索引是偶数的元素 xff0c
  • 第7章艺术编程Ajax的学习

    终于学到Ajax以前一直没接触到一直以为很NB xff0c 对这些内容我基本上是个小白中的小白哎 xff0c 继续加油 Ajax可以做到只更新页面的一下部分 xff0c 其他部分不需要重新加载 下面就是根据书上的内容所写 HTML lt d
  • 函数是否加括号的问题

    lt a onclick 61 34 fun 34 gt lt a gt 这里有括号 document getElementById 34 ID 34 onclick 61 fun 这里不可以有括号 为什么会有这样的不同 首先加上括号是执行
  • this的详细分析加案例

    this对象是在函数运行时候基于函数的执行环境 xff08 上下文 xff09 绑定的 方法调用模式函数调用模式改造器调用模式apply call bind调用模式 1 方法调用模式 函数有所属对象 xff0c 也就是这个函数是myObje
  • 构造函数与原型链和面向对象的学习(一)

    什么是构造函数 构造函数就是一个普通的函数 xff0c 里面可以写任何语句 逻辑语句或DOM操作 xff0c 可以new出新的实例 xff0c 使其实例可以共享构造函数的原型 第一个例子 function Fun this name 61
  • 构造函数与原型链和面向对象的学习(二)

    原型链 proto proto 也就是对象的 prototype 属性 每一个函数都有一个属性叫做prototype 指向一个对象 不是函数就没有这个属性 这个对象叫原型对象 当这个构造函数被new的时候 xff0c 他的每一个实例对象的

随机推荐

  • 构造函数与原型链和面向对象的学习(三)

    小案例 xff08 红绿灯 xff09 下面对面向对象写个小案例 xff08 红绿灯 xff09 上面是原图 用来来实现点击图片 xff0c 红绿灯的颜色改变 xff0c 控制背景图片的定位来改变 点击一下 就是要完成上面的效果 如果只要实
  • js中的预编译和作用域链

    预编译目的 1 定义作用域中的初始化词法环境 xff0c 而词法环境中有定于作用域 xff0c 从而规定了变量的作用域 2 先是在为undefined xff0c 减少运行时报错 形参去实参的区别 1 形参变量只有在被调用时才分配内存单元
  • ffmpeg视频处理神器学习基础笔记

    FFmpeg文档汇总 xff1a https ffmpeg org documentation html FFmpeg filters文档 xff1a https ffmpeg org ffmpeg filters html 视频处理 视频
  • Vue.js动画和过渡

    vue中的过渡与动画 过滤 把需要添加动画效果的DIV放到transition标签 之后就会发生以下3个步骤 自动嗅探目标元素是否应用了 CSS 过渡或动画 xff0c 如果是 xff0c 在恰当的时机添加 删除 CSS 类名 等下要写的6
  • Vue.js使用keyframes动画

    lt DOCTYPE html gt lt html gt lt head gt lt meta charset 61 34 utf 8 34 gt lt title gt Vue中css动画的原理 lt title gt lt scrip
  • Vue.js使用animate.css框架

    1 如何使用animate框架 lt DOCTYPE html gt lt html gt lt head gt lt meta charset 61 34 utf 8 34 gt lt title gt Vue中css动画的原理 lt t
  • vue.js中添加动画

    通过触发事件 xff0c 改变data中的值 xff0c 或者改变点击标签元素上的属性值 lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 6
  • 多个元素和列表的过渡

    多个元素 lt DOCTYPE html gt lt html lang 61 34 en 34 gt lt head gt lt meta charset 61 34 UTF 8 34 gt lt title gt 多个元素的组件的过渡动
  • flex弹性布局的学习

    布局的传统解决方案是基于盒状模型 xff0c 依赖 display 43 position 43 float 方式来实现 xff0c 灵活性较差 2009年 xff0c W3C提出了一种新的方案 Flex xff0c Flex是Flexib
  • 震惊!Ajax项目中的使用

    啊啊 xff01 实习第一天写了个移动端的分享列表 就在第三天我们的技术大佬亲自教我们如何对接后台 当然用的是我写的移动端的分享列表 虽然这次应用不是很深入 xff0c 但还是比较广泛 用到了Ajax xff0c sui框架 zepto x
  • 关于viewport视口的学习

    简单来说 lt meta name 61 34 viewport 34 content 61 34 width 61 device width initial scale 61 1 0 34 gt content属性值 width 可视区域
  • 淘宝的H5布局

    利用viewport和rem布局实现的淘宝布局 下面先看看em布局的原理 em作为font size的单位时 xff0c 其代表父元素的字体大小 xff0c em作为其他属性单位时 xff0c 代表自身字体大小 MDN em作为字体单位 x
  • css的优先级

    优先级 浏览器通过优先级来判断哪些属性值与一个元素最为相关 xff0c 从而在该元素上应用这些属性值 优先级是基于不同种类选择器组成的匹配规则 优先级是如何计算的 优先级就是分配给指定的 CSS 声明的一个权重 xff0c 它由 匹配的选择
  • Django设置分享到微信好友和朋友圈时的标题、摘要、链接和图片

    主要参考官方文档 1 前端分享给好友和朋友圈的js代码 share html lt DOCTYPE html gt lt html lang en gt lt head gt lt meta charset UTF 8 gt lt meta
  • 孙其功陪你学之——如何将shell命令的返回值赋值给应用程序的变量

    如何将shell命令的返回值赋值给应用程序的变量 博主最近做了个路由器的项目 xff0c 需要得到路由器现在网络状态和参数 xff0c 使用UCI get 获得 xff0c 但是使用了system xff08 UCI get xff09 之
  • shell编程2条件语句

    文章目录 shell编程之条件语句1 条件测试1 1 返回值1 2 test 2 文件测试3 整数值比较4 逻辑测试5 if语句5 1 单分支 if 语句5 2 双分支 if 语句5 3 多分支 if 语句 6 case 语句7 实验7 1
  • html和css的hack的学习

    在整理基础的时候总结 html和css的hack的学习 hack是什么 xff1f 就是针对不同的浏览器写不同的css样式让各浏览器能达到一致的渲染效果 xff0c hack分为HTML和CSS HTML hack lt if lte IE
  • 数组的迭代与归并的方法

    迭代的作用 xff1a 减少代码量 xff1a 例如因为map xff0c filter方法会自动生产数组不用自己在for创建 xff0c 有利于性能优化 xff1b 和无需知道对象的长度 补充19 6 11 xff1a 迭代的方法是表达式
  • js数组的常见属性和方法

    属性 strong length strong 是Array的实例属性 返回或设置一个数组中的元素个数 该值是一个无符号 32 bit 整数 xff0c 并且总是大于数组最高项的下标 xff0c 不只是可读 Array prototype
  • js闭包的作用和应用的学习

    什么是闭包 一个函数和对其周围状态 xff08 lexical environment xff0c 词法环境 xff09 的引用捆绑在一起 xff08 或者说函数被引用包围 xff09 xff0c 这样的组合就是闭包 xff08 closu