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对象 当前浏览器窗口对象 ...
随机推荐
- Javascript判断Crontab表达式是否合法
这段时间在做Quartz任务调度,使用的Crontab表达式实现的.Crontab由前端页面输入,作为参数穿入后台. 虽然Quartz具有校验Crontab表达式的方法,如下: boolean cro ...
- ios中Pldatabase的用法(2)
@implementation AppGlobal static NSString* strHostName; static NSString* strVersion; static PLSqlite ...
- SpringBoot开发项目,引入JPA找不到findOne方法
写在前面 开发SpringBoot的DAO层之后,去测试的时候,发现findOne()这个方法找不到了,查看了对应的表字段名和实体类的属性都一致 网上有通过降低版本解决的, 方式太牵强. 还有一种方式 ...
- Node单线程高并发原理
一.node是如何处理web请求的 浏览器中的js是单线程的,node也是单线程的.这个单线程相当于一个大管家,一切大小事务都要经过他的手才能办成,它总是把IO任务放入到任务池中. 虽然说是单线程,但 ...
- 如何在windows server 2008 部署asp.net mvc
我们做好的asp.net mvc网站,要部署到windows server 2008(IIS7.0)网站,首先要安装好.net framework 4.0,开发工具VS2010,VS2012,VS20 ...
- 【Spring】SpringMVC之REST编程风格
REST架构是一个抽象的概念,目前主要是基于HTTP协议实现,其目的是为了提高系统的可伸缩性.降低应用之间的耦合度.便于架构分布式处理程序.当使用多种语言进行开发的时候,每一种语言对URL的处理不同, ...
- process credentials(一)
一.介绍 当linux系统中的一个进程运行起来的时候,总是要访问系统的资源,访问文件或者向其他的进程发送信号.系统是否允许其进行这些操作?系统是根据什么来判断该进程的权限?这些问题是和进程信任状(pr ...
- 【iOS开发-36】Bundle Identifier的中文字符变成-的问题
在创建新项目时,Bundle Identifier=Organization Identifier+Product Name.可是它们对中文的识别统一变成短横线 - . 所以在创建多个项目的时候,须要 ...
- 跟我学SharePoint 2013视频培训课程——探索默认的列表和库(6)
课程简介 第6天,探索默认的列表和库. 视频 SharePoint 2013 交流群 41032413
- PMD-Java 代码检查工具对 error 和 warning 的配置
PMD是一款优秀的Java程序代码检查工具.该它可以检查Java代码中是否含有未使用的变量.是否含有空的抓取块.是否含有不必要的对象等. 但在使用过程中,你会项目中发现存在大量的 PMD 插件报出的 ...