关于js闭包的误区
一直以为js的闭包只是内部函数保存了一份外部函数的变量值副本,但是以下代码打破了我的认识:
function createFunctions()
{
var result = new Array(); for(var i=0;i<10;++i)
{
result[i] = function()
{
return i;
}
} return result;
} var funcs = createFunctions();
for(var i=0;i<10;++i)
{
console.log(funcs[i]());
}
执行结果是10个10 而不是0-9
看了JS高级编程7.2.1之后才明白 变量i并不是存在于匿名函数的局部变量表,而是存储在createFunctions的活动对象表(存储参数和局部变量)中。并且在创建函数的定义过程中匿名函数只是被定义而没有被执行。直到后面输出的循环被定义的匿名函数们才得以执行,而这时候它们的活动对象表里并不存在i,然后它们就会从作用域链向上查找createFunctions的活动对象表中的i。这时i的值已经是10,因此它们的执行结果全是10。
以下代码在闭包外部再加入了一个含参数的闭包,并且在定义之后调用,传递进去当前的i。这时这层新增的闭包活动对象表中含有参数num会存储i的当前值。这样结果就是0-9了:
function createFunctions()
{
var result = new Array(); for(var i=0;i<10;++i)
{
result[i] = function(num)
{
return function(){
return num;
}
}(i);
}
return result;
} var funcs = createFunctions();
for(var i=0;i<10;++i)
{
console.log(funcs[i]());
}
闭包的活动对象表中并不会包含this,this是当前执行上下文中的概念,会随着调用环境而变化。
name = "global name"
var obj = {
name:"object name",
func:function()
{
return function(){
return this.name;
}
}
}
console.log(obj.func()()); var obj2 = {
name:"object name",
func:function()
{
that = this;
return function(){
return that.name;
}
}
}
console.log(obj2.func()()); var obj3 = {
name:"object name",
func:function()
{
return this.name;
}
}
console.log(obj3.func());
console.log((obj3.func)());
console.log((obj3.func = obj3.func)());
输出结果:
global name
object name
object name
object name
global name
第一个输出 因为this并不在活动对象表里,闭包在调用的地方才获得当前的this,也就是全局对象
第二个输出 因为闭包定义之前取了this存到外层函数的that变量,用that就可以得到自定义对象
第3,4个输出 没有闭包 直接输出this
第五个输出 因为赋值表达式取结果的操作把当前的上下文变成了全局的,可以当做赋值操作不属于任何对象因此得到的是全局对象
关于js闭包的误区的更多相关文章
- js闭包的作用域以及闭包案列的介绍:
转载▼ 标签: it js闭包的作用域以及闭包案列的介绍: 首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几 ...
- 大部分人都会做错的经典JS闭包面试题
由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...
- Js闭包常见三种用法
Js闭包特性源于内部函数可以将外部函数的活动对象保存在自己的作用域链上,所以使内部函数的可以将外部函数的活动对象占为己有,可以在外部函数销毁时依然存有外部函数内的活动对象内容,这样做的好处是可 ...
- js闭包之初步理解( JavaScript closure)
闭包一直是js中一个比较难于理解的东西,而平时用途又非常多,因此不得不对闭包进行必要的理解,现在来说说我对js闭包的理解. 要理解闭包,肯定是要先了解js的一个重要特性, 回想一下,那就是函数作用域, ...
- (原创)JS闭包看代码理解
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...
- js闭包理解
js闭包的作用是使函数外可以访问函数内部的变量,是通过 在函数内部 定义 访问函数内变量 的函数实现的,内部的一个函数产生一个闭包 function a() { var i=0; return fun ...
- js闭包理解实例小结
Js闭包 闭包前要了解的知识 1. 函数作用域 (1).Js语言特殊之处在于函数内部可以直接读取全局变量 <script type="text/javascript"> ...
- Js闭包的用途
本来想总结一点JavaScript中的闭包的一些用法,在查资料的时候发现了一篇很好的文章,就转过来收藏了,下面附上传送门: js闭包的用途 ---------sunlylorn 我们来看看闭包的用途. ...
- js闭包和ie内存泄露原理
也议 js闭包和ie内存泄露原理 可以, 但小心使用. 闭包也许是 JS 中最有用的特性了. 有一份比较好的介绍闭包原理的文档. 有一点需要牢记, 闭包保留了一个指向它封闭作用域的指针, 所以, 在给 ...
随机推荐
- SQL 会议消费记录统计
统计 /****** Object: Procedure [dbo].[JOB_UP_Summit_UserConfStat] Script Date: 2014-3-17 10:00:50 **** ...
- [转]javascript eval函数解析json数据时为什加上圆括号eval("("+data+")")
javascript eval函数解析json数据时为什么 加上圆括号?为什么要 eval这里要添加 “("("+data+")");//”呢? 原因在于: ...
- ASPNET_MVC学习中的疑问
1.在mvc..net4.5.Entity Framewor都提供了多种验证规则. 请问,其中不需要提交到服务器验证的验证,是否是在客户端就完成的,还是说像之前的aspnet一样,都得提交到服务器验 ...
- tomcat7 ajax请求服务中文乱码
在确保请求服务编码格式为utf-8的情况下,确保tomcat的配置 <Connector connectionTimeout="20000" port="8080& ...
- 世界国家 的数据库sql
, '中国', 'CHINA'); , '阿尔巴尼亚', 'ALB'); , '阿尔及利亚', 'DZA'); , '阿富汗', 'AFG'); , '阿根廷', 'ARG'); , '阿拉伯联合酋长 ...
- iOS学习之代码块(Block)
代码块(Block) (1)主要作用:将一段代码保存起来,在需要的地方调用即可. (2)全局变量在代码块中的使用: 全局变量可以在代码块中使用,同时也可以被改变,代码片段如下: ;//注意:全局变量 ...
- Android启动标记
1. Task是包含一系列Activity的堆栈, 遵循先进后出原则. 2. Task默认行为: (1) 前提: Activity A和Activity B在同一个应用中. 操作: Activity ...
- 关于C#的委托(delegate)的自我理解
首先描述一个事情,一个老师饿了,他要去买东西填饱肚子,然后他发现他的学生“小李”在玩,没学习,于是就委托“小李”去帮他买吃的. 根据这件事我们来分析: 首先得有个老师(老师饿了是他的方法,老师买东西也 ...
- vs2012安装Microsoft.AspNet.WebApi.WebHost
工具---库程序包管理器---程序包管理器控制台:输入下面命令: Install-Package Microsoft.AspNet.WebApi.WebHost
- 41、javaMail机制
SMTP 是一种TCP协议支持的提供可靠且有效电子邮件传输的应用层协议.SMTP 是建立在 TCP上的一种邮件服务,主要用于传输系统之间的邮件信息并提供来信有关的通知. package com.ith ...