javascript基础拾遗(四)
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基础拾遗(四)的更多相关文章
- javascript基础拾遗(十一)
1.DOM操作 1)查找 //根据id查找 document.getElementById() //根据html标签查找 documnet.getElementByTagName() //根据样式cl ...
- 前端开发之JavaScript基础篇四
主要内容: 1.定时器 2.正则表达式入门 3.元字符 4.正则表达式实战运用 一.定时器 javaScript里主要使用两种定时器,分别是:setInterval()和setTimeout(). 1 ...
- JavaScript 基础第四天
一.前言 昨天我们了解了Js的很重要的一个概念叫做函数,函数就是对于冗余和垃圾代码的一种封装机制.简单的讲就是为了能让程序更好更快的执行我们将一些重复性的代码提取,封装成一个有名字的小盒子,等到我们需 ...
- javascript基础(四)语句
原文http://pij.robinqu.me/ for/in语句也使用for关键字,但它是和常规的for循环完全不同的一类循环.语法: for (variable in object) statem ...
- JavaScript基础学习(四)—Object
一.Object的基本操作 1.对象的创建 在JavaScript中,创建对象的方式有两种:构造函数和对象字面量. (1)构造函数 var person = new Object( ...
- JavaScript基础(四)
十六.client.offset.scroll系列 1.client系列 代码如下: <!DOCTYPE html> <html> <head> <meta ...
- javascript基础拾遗(十三)
1.jQuery的特点 jQuery是目前非常流行的javascript库,理念是"Write Less,Do More" 1)消除浏览器差异 2)简洁的操作DOM方法 3)轻松实 ...
- javascript基础拾遗(十二)
1.javascript的单线程特性 在javascript中,所有的代码都是单线程的 因此所有的网络操作,浏览器事件,都必须是异步执行的,异步执行的逻辑是回调. function callback( ...
- javascript基础拾遗(十)
1.支持ES6标准的浏览器 IE10+ Chrome Safari Firefox 移动端浏览器统一都支持 需要注意的是,不同浏览器对各个特性的支持也不一样 2.window对象 当前浏览器窗口对象 ...
随机推荐
- CPP复习笔记 3
--------------- CPP函数编译原理和成员函数的实现 从上节的分析中能够看出.对象的内存中仅仅保留了成员变量,除此之外没有不论什么其它信息,程序运行时不知道 stu 的类型为 Stude ...
- ACM退役前2个月总结
这个时候是该好好地反省一下自己了!曾经的时候为了队伍能打出很多其它的题,我硬是看了ACM的非常多模块!也会了非常多的模板!可是如今我痛苦地发现比赛还是我一人单挑的局面!如今我也遇见了一个瓶颈了,那就是 ...
- Dockerfiler如何使用多个启动命令entrypoint
两个办法,一个是CMD不用中括号框起来,将命令用"&&"符号链接: # 用nohup框起来,不然npm start执行了之后不会执行后面的 CMD nohup sh ...
- (原)torch中threads的addjob函数使用方法
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6549452.html 参考网址: https://github.com/torch/threads#e ...
- Xcode使用小技巧-filter查找功能和查看最近修改的文件
今天偶然发现了关于Xcode的一个小技巧: 1.查看最近修改的文件 2.使用filter查找制定文件 没错,就是下面这个东西,很容易忽略的一个小工具,在Xcode左下角位置. 通过这个,我们能够在整个 ...
- swift类型转换之Could not cast value of type xxx to xxx错误的一种特殊情况记录
之前swift项目打包成Framework静态库,提供给OC项目套入使用时,有时会抱这样一个错误: 这个错误发生的概率比较随机,有时会,有时不会,而且这句话在swift中的使用,是做model类型强制 ...
- jQuery对象复制
// 浅层复制(只复制顶层的非 object 元素) var newObject = jQuery.extend({}, oldObject); // 深层复制(一层一层往下复制直到最底层) var ...
- hihocoder 1638:多级并查集
题目链接 并查集可以用于聚类. import java.io.FileInputStream; import java.io.FileNotFoundException; import java.ut ...
- Html5 reset表 2015年1月7日15:02:14
/* HTML5 Reset :: style.css ---------------------------------------------------------- We have learn ...
- 绿色版mysql注册卸载服务
如果直接用绿色版的mysql,则下载后解压,只需对目录下的my.ini文件的basedir(mysql的基本目录)和datadir(mysql数据目录)指定就可以,如下所示. #Path to ins ...