[Effective JavaScript 笔记] 第11条:熟练掌握闭包
理解闭包三个基本的事实
第一个事实:js允许你引用在当前函数以外定义的变量。
function makeSandwich(){
var magicIngredient=”peanut butter”;
function make(filling){
return magicIngredient+’and ’+filling;
}
return make(‘jelly’);
}
makeSandwich();//”peanut butter and jelly”
图上直接指出如下
第二个事实:即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量。
function sandwichMaker(){
var magicIngredient=”peanut butter”;
function make(filling){
return magicIngredient+’and ’+filling;
}
return make;
}
var f=sandwichMaker();
f(“jelly”);//”peanut butter and jelly”
f(“bananas”);//”peanut butter and bananas”
f(“marshmallows”);//”peanut butter and marshmallows”
还是上图标识
原理:js的函数值包含了比调用它们时执行所需要的代码还要多的信息。而且js函数值还在内部存储它们可能会引用的定义在其封闭作用域的变量。那些在其所涵盖的作用域内跟踪变量的函数被称为闭包。make函数就是一个闭包。其代码引用了两个外部变量:magicIngredient和filling。每当make被调用时,其代码都能引用到这两个变量,因为该闭包存储了这两个变量。
函数可以引用在其作用域内的任何变量,包括参数和外部函数变量。
function sandwichMaker(magicIngredient){
function make(filling){
return magicIngredient+”and ”+filling;
}
return make;
}
var hamAnd=sandwichMaker(“ham”);
hamAnd(“cheese”);//”ham and cheese”
hamAnd(“mustard”);//”ham and mustard”
var turkeyAnd=sandwichMaker(“trukey”);
turkeyAnd(“Swiss”);//”trukey and Swiss”
turkeyAnd(“Provolone”);//”trukey and Provolone”
闭包是js最优雅、最有表现力的特性之一,也是许多惯用法的核心。js还提供了一种更为方便构建闭包的字面量语法--函数表达式。
function sandwichMaker(magicIngredient){
return function(filling){
return magicIngredient+”and ”+filling;
}
}
请注意,该函数表达式是匿名的。由于只需要产生一个新值,而不需要在局部使用,所以没必要给该函数命名。
第三个事实:闭包可以更新外部变量的值。
实际上,闭包存储的是外部变量的引用,而不是它们的值的副本。因此任何具在访问这些外部变量的闭包,都可以进行更新。
function box(){
var val=undefined;
return {
set:function(newVal){val=newVal},
get:function(){return val},
type:function(){return typeof val}
}
}
var b=box();
b.type();//”undefined”
b.set(98.6);
b.get();//98.6
b.type();//”number”
这个例子里产生了一个包含三个闭包的对象。这三个闭包是set,get和type属性。它们共享访问val变量。
提示
- 函数可以引用定义在其外部作用域的变量
- 闭包比创建它们的函数有更长的生命周期
- 闭包在内部存储其外部变量的引用,并能读写这些变量
后记
这个部分,这觉得这里讲得已经很清楚,如果想再深入去了解,可以去看高3上面关于闭包的讲解。
里面对作用域链,执行环境,变量对象,都有详细说明。
[Effective JavaScript 笔记] 第11条:熟练掌握闭包的更多相关文章
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [Effective JavaScript 笔记]第35条:使用闭包存储私有数据
js的对象系统并没有特别鼓励或强制信息隐藏.所有的属性名都是一个字符串,任意一个程序都可以简单地通过访问属性名来获取相应的对象属性.例如,for...in循环.ES5的Object.keys()和Ob ...
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
- [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符
“1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- [Effective JavaScript 笔记]第50条:迭代方法优于循环
"懒"程序员才是好程序员.复制和粘贴样板代码,一但代码有错误,或代码功能修改,那么程序在修改的时候,程序员需要找到所有相同功能的代码一处处进行修改.这会使人重复发明轮子,而且在别人 ...
- [Effective JavaScript 笔记]第19条:熟练掌握高阶函数
高阶函数介绍 高阶函数曾经是函数式编程的一个概念,感觉是很高深的术语.但开发简洁优雅的函数可以使代码更加简单明了.过去几年中脚本语言采用了这些个技术,揭开了函数式编程的最佳惯用法的神秘面纱.高阶函数就 ...
- [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑
构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...
- [Effective JavaScript 笔记]第46条:使用数组而不要使用字典来存储有序集合
对象属性无序性 js对象是一个无序属性集合. var obj={}; obj.a=10; obj.b=30; 属性a和属性b并没有谁前谁后之说.for...in循环,先输出哪个属性都有可能.获取和设置 ...
随机推荐
- 4G时代的抢钱之道
最近最大的事件恐怕就是移动的4G上线了,50元600M起计价,上网速度最高理论到达100Mbps,相当于一秒下载10MB的数据,或者是一分钟下载一张VCD(600M)电影. 当然,对于这样的流量套餐, ...
- css清楚浮动的几种常用方法
请先看博客:http://www.jb51.net/css/173023.html
- jQuery使用之(三)处理页面的元素
对于页面的元素,在DOM编程中可以通过各种查询.修改手段进行管理,非常麻烦.jQuery提供了一整套的方法来处理页面的元素.包括元素的内容.复制.移动和替换等.本节将介绍一些常用的内容. 1.直接获取 ...
- Qt *.pro编写一般规则
qmake 之 CONFIG 与 QT 乱谈 看qtcn论坛中经常有人忘记 QT+=network 等语句.随便写写吧,或许对他人有帮助. 写来写去,发现越写越乱,就这样吧,反正主要的内容很简单. d ...
- java Thread编程(三) 同步的两种不同实现方式
1,创建需要同步的对象(方式一) package concurrency; public class Bank { private double amount; public Bank(double ...
- Java基础-String、StringBuffer、StringBuilder
看下面这段代码: public class Main { public static void main(String[] args) { String string = ""; ...
- 【ZOJ 3609】Modular Inverse
题 题意 求a关于m的乘法逆元 分析 a x ≡ 1 (mod m) 等价于 ax+my=1 求x的最小正数(不能是0,我就WA在这里了). 当m=1时,或者 gcd(a,m)!=1 时x不存在. 所 ...
- BZOJ-3226 校门外的区间 线段数+拆点(类似的思想)
shabi题....bzoj关键字检查freopen??可怕,,1A的卡了一小时.... 3226: [Sdoi2008]校门外的区间 Time Limit: 10 Sec Memory Limit: ...
- CCNET配置文件配置工具
当我们在使用CruiseControl.NET进行配置的时候,你会发现配置文件是个非常头痛的事,无从下手,下面我在google找了一个09年的工具,主要是针对CruiseControl.NET进行配置 ...
- NOIP2005提高组 过河
题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...