javascript closure
来源:互联网 发布:手机网络看不了视频 编辑:程序博客网 时间:2024/05/16 08:38
闭包:主要是解决
1、函数闭包的出现是javascript 无权限概念,一个函数里面有全局变量,
这样就麻烦了,大家都能用,存的时间长,所以闭包里的变量只能自己函数用,
成了私有变量。
2、一个函数也是对象,一个函数可以建立多个实例,那么每次建立实例时不用总是去初始化私有变量。
这样会大大减少工作量和内存。
参考文章:https://stackoverflow.com/questions/111102/how-do-javascript-closures-work?answertab=active#tab-top
1、First-class function:
如果把函数看成是首类函数,哪么这就意味着javascript 语言,可以以把函数的作为参数传递,把函数当返回值,且将他们赋值给变量或将它们存储在数据结构中。
2、a higher-order function:
1>采用一个或多个函数作为参数
2>返回值,是一个函数。
3、 a closure
第一:一个闭包是支持first-class functions的一种方式,
1》它是一个表达式,在它的作用域内({ })能引用变量(当它第一次声明时),
2》 能赋值给一个变量,
3》可以当函数的参数传递,
4》可以当函数的返回值。
第二:或者, a closure 是一个 stack frame,当函数开始执行时分配一个stack frame(这里和java 方法一样),且当函数返回后,并没有释放stack frame(好像一个堆栈框架分配在堆上,而不是堆栈上!)。
例子1:
function sayHello(name) {var text = 'Hello ' + name;
var say = function() { console.log(text); }
say();
}
sayHello('Joe');
结果:
例子2:能赋值给一个变量
下面返回一个函数的应用,和java一样,有了引用,就可以和某个对象相连,而这里表示和函数相连。
function sayHello2(name) { var text = 'Hello ' + name; // Local variable var say = function() { console.log(text); }//赋值给一个变量 return say;}var say2 = sayHello2('Bob');say2(); // logs "Hello Bob"
say,say2 变量是指向一个函数的指针。但和Java不一样,这里的引用变量有两个指针,一是指向一个函数,一个隐含的指向一个闭包函数。
上面的代码有一个闭包,因为一个匿名函数 function() { console.log(text); } 是声明在另一个function, sayHello2() 里面. In JavaScript, 如果你使用 function keyword 在另一个函数里面, 你正在建立一个闭包。
在java中,在一个函数返回后,所有的本地变量不再有用,因为stack frame回收了。
在JavaScript, 如果你声明一个函数在另一个函数里面,然后在你调用函数后,本地变量能保持继续可用。例如:调用sayHello2()后,再调用say2(),sayHello2()函数本地变量text继续有效
function() { console.log(text); } // Output of say2.toString();
看看
say2.toString()的输出
, 我们能看见代码指向变量text. 匿名的函数能引用text
变量,这个变量持有'Hello Bob',因为sayHello2()本地变量保存在一个闭包里
.
魔法是在 in JavaScript 里,一个函数应用同时有一个秘密引用建立它的closure — similar to how delegates 是一个方法指针+一个对象的秘密引用.
例 3:和例子2一样
This example shows that the local variables are not copied — they are kept by reference. It is kind of like keeping a stack-frame in memory when the outer function exits!
function say667() { // Local variable that ends up within closure var num = 42; var say = function() { console.log(num); } num++; return say;}var sayNumber = say667();sayNumber(); // logs 43
例 4:
所有三个全局函数对同一个闭包公共的引用,因为他们都被声明在单个的setupSomeGlobals()
.里面。
var gLogNumber, gIncreaseNumber, gSetNumber;function setupSomeGlobals() { // Local variable that ends up within closure var num = 42; // Store some references to functions as global variables gLogNumber = function() { console.log(num); } gIncreaseNumber = function() { num++; } gSetNumber = function(x) { num = x; }}setupSomeGlobals();gIncreaseNumber();gLogNumber(); // 43gSetNumber(5);gLogNumber(); // 5var oldLog = gLogNumber;setupSomeGlobals();gLogNumber(); // 42oldLog() // 5
The three functions have shared access to the same closure — the local variables of setupSomeGlobals()
when the three functions were defined.
注: that in the above example, 如果你再次调用setupSomeGlobals()
, 然后一个新的 closure (stack-frame!) 被建立.
旧的
gLogNumber
, gIncreaseNumber
, gSetNumber
变量被新函数重写,新函数有一个新的closure. (In JavaScript, 无论你是么时候把一个函数声明在另一个函数里面,当外面的函数重新调用时,里面的函数重新 建立)、
例5: 函数作参数
如果你在一个循环中定义一个函数,闭包中的局部变量不会像您最初想象的那样起作用。
下面表示数组元素是一个函数指针,哪么 fnlist[j](),可以是内部函数调用,但是闭包的item和i没有保存,导致后面调用不起作用。
而且闭包的变量保存item=item3,i=3,中间的数据没有保存。
function buildList(list) { var result = []; for (var i = 0; i < list.length; i++) { var item = 'item' + i; result.push( function() {console.log(item + ' ' + list[i])} ); } return result;}function testList() { var fnlist = buildList([1,2,3]); // Using j only to help prevent confusion -- could use i. for (var j = 0; j < fnlist.length; j++) { fnlist[j](); }} testList() //logs "item2 undefined" 3 times
pointer = function() {console.log(item + ' ' + list[i])};result.push(pointer);
例6:javascript首先把变量移到顶部,然后运行,只要在{}定义的变量,里面所有函数都能用,函数和变量的放置的顺序无关,也是javascript的第一大特点。sayAlice()=say=指针,指向内部函数。
这里的alice将移到say上面( variable hoisting)),所有匿名函数可以用。
function sayAlice() { var say = function() { console.log(alice); } // Local variable that ends up within closure var alice = 'Hello Alice'; return say;}sayAlice()();// logs "Hello Alice"
例7:函数作为返回值,num,anArray,本地变量保存变化的值。
function newClosure(someNum, someRef) { // Local variables that end up within closure var num = someNum; var anArray = [1,2,3]; var ref = someRef; return function(x) { num += x; anArray.push(num); console.log('num: ' + num + '; anArray: ' + anArray.toString() + '; ref.someVar: ' + ref.someVar + ';'); }}obj = {someVar: 4};fn1 = newClosure(4, obj); //返回内部匿名函数的指针。fn2 = newClosure(5, obj);fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;//调用内部函数fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;obj.someVar++;fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;
var value = 0;
return {
increment:function (inc) {
value += typeof inc === 'number' ?inc : 1;
},
getValue: function ( ) {
returnvalue;
}
};
}( ));
**(function($, window) { })(mui, window);:就是立即执行,这是一个匿名函数,既然是函数,必须要调用,哪么调用直接放在定义后面(mui, window)
估计是浏览接收一个文件放入自己的缓存后,立即执行这个脚本。
- JavaScript - Closure
- Javascript Closure
- javascript Closure
- JavaScript Closure
- Javascript Closure
- javascript closure
- JavaScript closure
- javascript closure
- [JavaScript] Closure In JavaScript
- 诡异的JavaScript Closure
- 诡异的JavaScript Closure
- Javascript Closure[1]
- Javascript Closure[2]
- javascript 之 Closure
- Javascript闭包(Closure)
- Javascript--闭包(closure)
- Javascript闭包(Closure)
- 在Javascript中闭包(Closure)
- 多线程(4)—同步方法
- Hdu 6082 度度熊与邪恶大魔王 背包DP
- 有关Ajax套用问题,表格列表等宽属性,Mybatis从数据库读取数据。
- 游戏对象未激活时,无法调用awake() start()
- 一名3年工作经验的程序员应该具备的技能
- javascript closure
- Oracle学习笔记
- 解药还是毒药
- HDU 1176(动态规划矩阵)
- 二、头脑风暴汇集的问题原貌展现
- Java的集合与泛型
- 使程序在Linux下后台运行,程序运行前后台切换
- 一种删除集合List数据元素的陷阱,论Iterator的重要性
- Java 19:Spring 2(Bean运行时值注入:占位符和SpEL表达式 )