1.什么是闭包

正常函数,执行完毕后相关的参数,变量就释放掉了。

当一个函数的返回值是另一个函数时,该函数的相关参数和变量都会保存在返回的函数中,这种结构叫做闭包。

2.示例

计算数组和

function sum(arr) {
return arr.reduce(function (x,y) {
return x+y
})
}
result = sum([1,3,5])
console.log(result)

运行结果:9

如果我们不想立即求和,在后面才执行,该怎么做?

function lazy_sum(arr) {
var sum = function () {
return arr.reduce(function (x,y) {
return x+y
})
}
return sum
}
result = lazy_sum([1,3,5])
console.log(result())

lazy_sum([1,3,5])返回一个计算和的函数,[1,3,5]参数作为返回函数的变量,会一直被返回函数引用。result就是闭包函数。

3.闭包函数容易引发的问题

参数和变量会一直被返回函数引用,如果改变参数或变量的值,那么执行时引用的也是最新的值,

所以应该避免使用会发生变化的变量,作为闭包函数的参数或变量。如:

function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push(function () {
return i * i;
});
}
return arr;
} var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
f1()
f2()
f3()

运行结果:16 16 16

因为i的值已经发生改变了

4.必须引用会发生变化的变量情况

唯一的解决办法是将闭包函数中的变量的值固定,这样做,闭包函数已经不引用变量了,相当于使用常量。

如何把变量的值固定呢?

在闭包函数外层再包裹一层函数,将变量作为参数传递,并立即执行,这样闭包函数中变量的值就绑定了。

function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push((function (n) {
return function () {
return n * n;
}
})(i));
}
return arr;
} var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2]; f1(); // 1
f2(); // 4
f3(); // 9

5.闭包函数的作用

闭包函数引用的变量,外部无法访问,可以理解为一个静态私有变量。

可以想象的使用场景,如计数器等。

javascript基础拾遗(四)的更多相关文章

  1. javascript基础拾遗(十一)

    1.DOM操作 1)查找 //根据id查找 document.getElementById() //根据html标签查找 documnet.getElementByTagName() //根据样式cl ...

  2. 前端开发之JavaScript基础篇四

    主要内容: 1.定时器 2.正则表达式入门 3.元字符 4.正则表达式实战运用 一.定时器 javaScript里主要使用两种定时器,分别是:setInterval()和setTimeout(). 1 ...

  3. JavaScript 基础第四天

    一.前言 昨天我们了解了Js的很重要的一个概念叫做函数,函数就是对于冗余和垃圾代码的一种封装机制.简单的讲就是为了能让程序更好更快的执行我们将一些重复性的代码提取,封装成一个有名字的小盒子,等到我们需 ...

  4. javascript基础(四)语句

    原文http://pij.robinqu.me/ for/in语句也使用for关键字,但它是和常规的for循环完全不同的一类循环.语法: for (variable in object) statem ...

  5. JavaScript基础学习(四)—Object

    一.Object的基本操作 1.对象的创建      在JavaScript中,创建对象的方式有两种:构造函数和对象字面量.      (1)构造函数 var person = new Object( ...

  6. JavaScript基础(四)

    十六.client.offset.scroll系列 1.client系列 代码如下: <!DOCTYPE html> <html> <head> <meta ...

  7. javascript基础拾遗(十三)

    1.jQuery的特点 jQuery是目前非常流行的javascript库,理念是"Write Less,Do More" 1)消除浏览器差异 2)简洁的操作DOM方法 3)轻松实 ...

  8. javascript基础拾遗(十二)

    1.javascript的单线程特性 在javascript中,所有的代码都是单线程的 因此所有的网络操作,浏览器事件,都必须是异步执行的,异步执行的逻辑是回调. function callback( ...

  9. javascript基础拾遗(十)

    1.支持ES6标准的浏览器 IE10+ Chrome Safari Firefox 移动端浏览器统一都支持 需要注意的是,不同浏览器对各个特性的支持也不一样 2.window对象 当前浏览器窗口对象 ...

随机推荐

  1. @Transient注解的使用

    转自:https://blog.csdn.net/sinat_29581293/article/details/51810805 java 的transient关键字的作用是需要实现Serilizab ...

  2. jQuery对象复制

    // 浅层复制(只复制顶层的非 object 元素) var newObject = jQuery.extend({}, oldObject); // 深层复制(一层一层往下复制直到最底层) var ...

  3. keras中的loss、optimizer、metrics

    用keras搭好模型架构之后的下一步,就是执行编译操作.在编译时,经常需要指定三个参数 loss optimizer metrics 这三个参数有两类选择: 使用字符串 使用标识符,如keras.lo ...

  4. Cordova+jQuery Mobile+Spring REST

    Cordova可以方便地建立跨平台的移动应用,使用jQuery Mobile做手机界面,后台使用rest提供数据交互. 首先,使用jQuery Mobile建立一个页面: <!DOCTYPE h ...

  5. 浅谈iOS中MVVM的架构设计

    MVVM就是在MVC的基础上分离出业务处理的逻辑到viewModel层. M:  Model层是API请求的原始数据,充当DTO(数据传输对象),当然,用字典也是可以的,编程么,要灵活一些.Model ...

  6. Spring使用内存数据库二

    在上篇<Spring 使用内存数据库>中我们使用Hibernate作为ORM的框架,直接调用Hibernate的API进行相关的持久化操作,但在实际项目中,可能会由于公司规定等原因要求统一 ...

  7. TestNg的IReporter接口的使用

    IReporter接口是干嘛的?就是让用户自定义报告的,很多人想要自定义报告,于是乎找各种插件,比如什么testng-xslt啊,reportng啊,各种配置,最后出来的结果,还不能定制化,但为什么不 ...

  8. Log4j 基本配置示例

    1.log4j.properties log4j.rootLogger=INFO, stdout, fileout log4j.logger.TestProject=INFO log4j.append ...

  9. UNIX 家族及Linux

    Unix成长为一个非私有的操作系统,是因为1956年的AT&T公司受命于联邦去经营电报电话服务.当然也可以开发软件,甚至那个软件可以有”合理”收费的许可证,但是这个公司却被禁止从事任何和计算机 ...

  10. 【jsp】JSTL标签大全详解

    一.JSTL标签介绍 1.什么是JSTL? JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便,它与JSP动作标签一样,只不过它不是 ...