标签:比较 俄罗斯 href 来源 csharp 数据 ack 参数 通过
1.词法作用域: 简单地说子集能访问父级的变量, 说人话就是变量拿来就用不用传入
2.函数局部变量: 在函数体中以var 声明变量的为局部变量 + 函数传入的参数, 直接写变量名声明的变量是全局变量
3.局部变量生存期: 局部变量在函数函数的执行期间可用, 一旦执行过后,局部变量将不再可用
4.延长局部变量生存期: 现在问题来了,我想要延长局部变量的生存期,怎么办。(因为调用函数不仅仅是为了return, 有时候还需要保存函数中的状态, 或者实现类等等)
5.使用全局变量不好吗: 不好。有时函数内部成员不想被外部直接访问, 全局变量做不到;一般而言函数内部成员与外界成员如果重名也没什么关系, 但如果使用全局变量就要小心命名问题(还有很多问题)
6.闭包: 函数返回内部定义函数(的句柄) or 包含若干内部定义函数(句柄)的集合。说人话就是函数 return function(param){//code} 或者 return 一个array/dict,集合的值都是function(param){//code}(本来想贴代码来着但这个编辑器实在是太...),这些内部定义的function包含/使用了函数的局部变量。
7.所以闭包就是返回一个内部定义函数(句柄)or一个集合?: 可以这么理解,但是返回这个内部定义的函数(句柄) or 包含大量内部定义的函数(句柄)的array/dict的结果是维持了局部变量的生存期,也就是给局部变量续命。这个意义十分重大。
8.使用闭包: 调用函数→得到内部函数(句柄) or array/dict(包含大量内部函数句柄)→使用内部函数为局部变量续命
片面的总结一下:闭包就是两层看成一个整体。外层的function可以看做Java的class, 内层的function可以看做是类的函数成员。Java中实例化一个class用new, JavaScript调用外层函数可以看做实例化。Java中调用公开的方法是obj.func, JavaScript外层函数如果直接return function(param){}那直接拿着当函数用, 如果返回array/dict用法和java很相似obj.func。每调一次外层函数相当于不同的实例,不同实例相互独立。这个理解片面一点在于循环,在后面我有解释。
9.几个注意事项
(1)闭包很像一个2层俄罗斯套娃,就是一个函数必须套一个函数,外层函数返回内层函数,内层函数给外层函数的局部变量续命。如果包含若干内层函数, 则共享外层函数的局部变量。(一个函数f1被f2包裹(不管f2有没有被其他函数包裹, 被多少函数包裹),则f1可以享用f2的局部变量状态)
(2)先看代码
function setupHelp() { var helpText = [ {‘id‘: ‘email‘, ‘help‘: ‘Your e-mail address‘}, {‘id‘: ‘name‘, ‘help‘: ‘Your full name‘}, {‘id‘: ‘age‘, ‘help‘: ‘Your age (you must be over 16)‘} ]; for (var i = 0; i < helpText.length; i++) { document.getElementById(item.id).onfocus = function() { document.getElementById(‘help‘).innerHTML = helpText[i].help; } } } setupHelp();
大意是通过循环设置onfocus事件, 设置的手段就是赋予匿名function, 偏偏不巧的是匿名function内部包含了关于循环变量 i 的内容,不过也不奇怪, 如果用不到 i 我还用循环作甚。问题在于这个i不会很听话的0 1 2逐一赋予,当循环跑完再调用setupHelp函数的时候, i变成2, 所有匿名function中的item.help指向最后一项。怎么才能让 i 维持状态。
先分析这段代码。循环产生三个匿名function,这三个匿名function被setupHelp函数包裹,所以这三个function共享i变量,共享的意思是都是一个值。所以怎么解决i维持状态这个事呢?答案是再加一层function。内层的匿名function不管外层包裹多少function, 就是看最近包裹我的函数, 最近包裹我的函数传进来是几,我用了就能维持这个数据, 反正就是内层函数用了外层函数的局部变量维持了变量的空间。改动如下。
function makecallback(i){ return function(){ document.getElementById(‘help‘).innerHTML = helpText[i].help; } }
可能会想直接赋予一个匿名function和return一个匿名function有区别吗,其他语言可能没什么区别(不会碰到为了维持内部状态、让循环变量立刻生效必须闭包), 但是JavaScript就是这么蛋疼, 没有办法因为你没有选择。
吐槽时间:知乎上有个问题问JavaScript闭包的, 很多答案真是...有股论文风。不得不说搞前端的就是洋气, 解释起问题来就是一套一套的, 不过这也很职业有关。前端让人爽是目的之一, 所以会装逼是必修课。你看叶老师,龚大低调得很(虽然龚大最近开始炫富【大雾】)答案除了幽默一下就是比较干货了。当然知乎还是有很多前辈的, 所以我明明是个后端为什么开始学JavaScript, 明明我只想实现一个背景轮播图而已啊... ...
主要资料来源:https://developer.mozilla.org/cn/docs/Web/JavaScript/Closures
标签:比较 俄罗斯 href 来源 csharp 数据 ack 参数 通过
原文地址:http://www.cnblogs.com/CoconutBread/p/6754052.html