博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
学习总结 javascript 闭包
阅读量:5025 次
发布时间:2019-06-12

本文共 3297 字,大约阅读时间需要 10 分钟。

学习地址 :http://stackoverflow.com/questions/111102/how-do-javascript-closures-work 
1,关于闭包的简单实现
//example 1
function sayHello(name) {
var words = "hello," + name;
var sayForAlert = function () {
alert(words);
}
sayForAlert();
}
//sayHello("jack");
/*
An Example of a Closure
Two one sentence summaries:
a closure is the local variables for a function — kept alive after the function has returned, or
a closure is a stack-frame which is not deallocated when the function returns (as if a 'stack-frame' were malloc'ed instead of being on the stack!).
*/
function sayHello2(name){
  var words = "hello, "+name; //local variables;
  var sayForAlert =  function (){
alert(words);
  }
  
  return sayForAlert;
}
var say2 = sayHello2("lucy");
say2();
/*
一个函数的引用。作为一个參数返回回来。

在这里相当于返回一个函数的

指针。

sayForAlert 和 say2指向的是同一函数。

javascrip与c的一个重要差别在于c指针指向一个函数,而javascript是一个引用指向一个函数。

(相当于是隐藏性指针)。

在很多的语言中和c一样。当函数运行完毕后,本地的变量就不能再訪问。
由于其函数的堆栈被销毁。

在javascript中函数的里面能够在声明函数。而且本地的变量能够訪问,并
可心在声明的函数中返回。

*/
 
function saynumadd(){
 var num = 666;
 
 var showAlert = function(){
alert(num);
//num++;//place 2;
 }
 num++;//place 1;
 return showAlert;
}
var sayNumber = saynumadd();
sayNumber();//alert 667;
/*
note: 依据上面的运行结果来看num做为一个变量被保存起来在后面
函数的调用能够再获取到。

假设我们把num++;放到place2的位置

看到的结果就是666.说明函数的运行顺序运行 saynumadd() 运行过程
中 1。声明变量num,2,声明函数 showAlert,3,把变量num自添加1。
当我们运行 sayNumber()的时候看到的就是667 添加后被保存的结果。

*/
function setupSomeGlobals(){
var num = 666;
//store some references to function as global variables
getAlertNumber = function (){
alert(num);
}
getIncreaseNumber = function(){
num ++;
}
getSetNumber = function(x){
num = x;
}
}
setupSomeGlobals();
getIncreaseNumber();
getAlertNumber();
getSetNumber(10);
getAlertNumber();//10
setupSomeGlobals();
getAlertNumber();//666
/*
onte:
从上面的样例能够看出,
setupSomeGlobals 里面的三个函数被声明都有权限去訪问里面的变量。

 

假设我们又一次调用 setupSomeGlobals() 新的函数堆栈会被创建. 之前创建的getAlertNumber, getIncreaseNumber, getSetNumber 会被重写并有一个新的闭包. (在 JavaScript中, 不管不论什么候都能够在function的内部声明另外一个function,外面的function被调用的时候。里面的function都会被又一次创建.)
*/
function buildList( list ){
var result = [];
for (var i = 0 ; i<list.length; i ++){
var item = 'item' + list[i];
result.push(function(){alert(item +'    '+list[i])});
}
return result;
}
function testList(){
var fnList = buildList([1,2,3,4]);
for(var j=0; j < fnList.length; j ++){
fnList[j]();
}
}
testList();//alert item1  undefined;
/*
执行结果。能够说明function里面的function仅仅能够保存本地变量,不能保存參数变量。所以我们在使用封包函数要注意当中变量的作用域。
*/
function callLocalVar(){
var sayAlertName = function(){alert(name)}; 
var name = "jacy";
return sayAlertName;
}
callLocalVar()();//这样的写首先会运行callLocalVar再运行返回的sayAlertName;
/*
note:
总结闭包函数能够訪问到同一个域时定义的变量,不管是在这个闭包函数的前面还是后面。 仅仅要是同一个域就能够被訪问到。
*/
function checkClosure(someNum, someRef){
var num = someNum;
var arr = [1,2,3];
var ref = someRef;
return function(x){
num += x;
arr.push(num);
alert('num :'+num + ' \n arr :'+arr.toString()
+'\n ref.someVar'+ref.someVar);
}
}
var obj = {someVar:4};
var fn1 = checkClosure(4,obj);
var fn2 = checkClosure(5,obj);
fn1(1);// num: 5; arr: 1,2,3,5; ref.someVar: 4;
fn2(1);// num: 6; arr: 1,2,3,6; ref.someVar: 4;
obj.someVar ++;
fn1(2);// num: 7; arr: 1,2,3,5,7; ref.someVar: 5;
fn2(2);//num: 8; arr: 1,2,3,6,8; ref.someVar: 5;
/*
note:
这里的写法攻克了參数变量不能被保存的问题,仅仅要创建一个本地作用域一个变量来接收这个參数变量的值就能够了。

能够说明不同的作用域,互相不影响。

*/

转载于:https://www.cnblogs.com/jzdwajue/p/7040109.html

你可能感兴趣的文章
IOS程序的启动过程
查看>>
连接Linux下 XAMPP集成环境中部署的禅道的数据库MariaDB
查看>>
Java操作Excel和Word
查看>>
Oracle 体系结构之ORACLE物理结构
查看>>
ORA-12538: TNS: no such protocol adapter
查看>>
盒子模型
查看>>
局域网协议
查看>>
[HNOI2012]永无乡 线段树合并
查看>>
Spring整合hibernate:3、使用XML进行声明式的事务管理
查看>>
SqlServer之Convert 函数应用格式化日期(转)
查看>>
软件测试领域中的10个生存和发展技巧
查看>>
Camera前后摄像头同时预览
查看>>
HDU 1856
查看>>
课堂作业01--架构师的职责
查看>>
iOS计算富文本(NSMutableAttributedString)高度
查看>>
2017/09/15 ( 框架2)
查看>>
Centos下源码安装git
查看>>
gulp-rev-append md5版本号
查看>>
IO流之File类
查看>>
sql 基础语句
查看>>