js闭包的概念
来源:互联网 发布:西北师大知行学院贴吧 编辑:程序博客网 时间:2024/04/30 09:44
引子:关于闭包
什么是闭包呢?
从定义上来看,所有的函数都可以是闭包。当一个函数在调用时,引用了不是自己作用域内定义的变量(通常称其为自由变量),则形成了闭包;闭包是代码块和创建该代码块的上下文中数据的结合。
例子: function mytest( ){
var test=10;
return function( ){
test++;
alert(test);
}
}
var atest = new mytest( ); //引用返回的函数
atest( ); // 11
atest( ); // 12
ps:注意运用闭包的常见错误-->for(var i,len=xx.length;i<len;i++)循环;当我们所引用的自由变量为i时,由于i一直在内存中没有释放,所以函数每次alert(i)时,其值均为最终的i;(例子很多,就不写了)
通过测试结果我们可以发现, 闭包会使该函数引用的变量一直在内存中,原因是什么呢?
简单的解释就是因为这个返回的函数引用了变量test;当浏览器解析到var atest=new mytest();这一行且mytes()函数执行完毕,准备内存释放时,发现所返回的函数引用了test变量。从而该出栈的并没有出去;
想完全弄清楚这个问题,我们还需要进一步理解AO(活动对象)和VO(变量对象)以及作用域链、执行上下文的问题。
那么这整个机制浏览器到底是怎么解析的呢?
不急,我们来看看执行上下文、作用域链、活动对象和变量对象;
写在前面的执行上下文:
a:定义:
globalContext
];
];
1、作用域链
首先,我们如何创建一个作用域呢,function()。函数是javascript中唯一一个能创建出作用域的,也就是说for、if、while的{}是不能创建出作用域的。区别c++中的块作用域{}。
一个函数的作用域创建后,将贯穿他的始“{”,终“}”,作用域
。这句话就应该着重理解贯穿2字了,若函数内部嵌套着多个函数,那么从最内层函数作用域依次往外就形成了作用链。
ps:需要我们理解作用域链的变量查找机制是由内往外的。先找自身作用域,再一次往外,若没有,则等同没有var时的声明(为全局添加了一个属性);
2、变量对象(Variable Object)、活动对象(Activation Object)
浏览器在对代码进行解析时,会先进行变量声明和函数声明以及函数形参声明;
(全局作用域下)那么这些优先声明的变量储存在哪里呢?
没错,就在变量对象中(抽象概念);活动对象怎么理解呢?
(VO === this === global)
--> 函数上下文变量对象FunctionContextVO
(VO === AO, 并且添加了<arguments>(形参类数组)和<formal parameters>(形参的值))
ps:在函数执行上下文中,VO是不能直接访问的,此时由活动对象扮演VO的角色。Arguments对象是活动对象的一个属性,它包括如下属性:
callee — 指向当前函数的引用
length — 真正传递的参数个数
properties-indexes (字符串类型的整数) 属性的值就是函数的参数值(按参数列表从左到右排列)。 properties-indexes内部元素的个数等于arguments.length. properties-indexes 的值和实际传递进来的参数之间是共享的。
现在让我们来串一下
1、全局执行上下文
创建global.VO
2、全局变量的赋值 | 调用函数()(激活)
激活函数后,会得到当前的AO,其中有内部函数的声明、内部变量的声明、形参
3、进入所激活的函数的上下文
进行所在作用域链上的变量的赋值 各种运算 (作用域链包含全局的VO,和当前执行上下文的AO)
4.a、若在函数中有内部函数调用(或自执行),重复3;
4.b 若返回一个函数(或其引用),且该函数有对自由变量的引用-->形成闭包-->作用域链机制依然有效-->当前已压入执行上下文堆栈的FunctionContext不会出栈;-->回到2;
4.c 正常return或正常结束,FunctionContext出栈;-->回到2;
5.所有代码执行完毕,程序关闭,释放内存。
注意两点:
1. this 是JavaScript的关键字,不是变量,因此每个函数调用都含有一个this值,闭包在外部函数之外是不可以访问this的,例如
var scope = "global scope";var o = {scope: "local scope", f:function () { return function (){ return this.scope; } }};var p = o.f();p();
输出gloval scope
var scope = "global scope";var o = {scope: "local scope", f:function () {var self = this;
return function (){ return self.scope; } }};var p = o.f();p();输出local scope
2. arguments 是每一个函数的实参列表,为了在闭包中访问外部函数的arguments就需要将外部函数的arguments赋值给局部变量进行使用
- js的闭包概念
- JS闭包的概念
- JS闭包的概念
- JS闭包的概念
- JS闭包的概念
- js 闭包的概念
- JS闭包的概念
- js的闭包概念
- js闭包的概念
- js 闭包概念
- 闭包的概念(js)
- js闭包的概念以及引入
- node.js 包的概念
- JS闭包函数概念
- js 闭包概念详解
- 【js思考】js闭包概念
- 关于JS-闭包概念的好文章
- js函数中 "闭包"概念的简单认识
- 消息游标
- 第十四周 折半查找算法的验证
- python爬取网页中javascript动态添加的内容(一)
- MarkdownPad 2 Pro 注册码与注册私钥,Windows平台Markdown编辑器
- jQuery制作无缝轮播
- js闭包的概念
- 编码的验证gbk,utf...
- Linux 驱动之模块参数和符号导出
- Android开发艺术探索笔记(3)- 进程和线程
- jdbc 规范
- 1111
- 推荐轻量高效无依赖的开源 JS 插件和库
- Android性能优化
- Json转化为Java对象(object,List等)