JavaScript闭包整理
来源:互联网 发布:php企业站源码 编辑:程序博客网 时间:2024/05/18 06:28
闭包:
在MDN中的解释:闭包是指那些能够访问独立(自由)变量的函数 (变量在本地使用,但定义在一个封闭的作用域中)。换句话说,这些函数可以“记忆”它被创建时候的环境。
简单理解就是:
如果一个函数会在其父级函数返回之后留住对父级作用域的链接的话,相关闭包就会被创建出来。
闭包#1:
var a = "global variable";
var F = function(){
varb = "local variable";
varN = function(){
varc = "inner local";
returnb;
}
returnN;
}
函数N有自己的私有空间,同时可以访问F()的空间和全局空间,所以b对它来说是可见的,因为F()是一个全局函数,所以可以将它的返回值赋值给其他全局变量,生成一个可以访问F()私有空间的新全局函数。
var inner = F();
inner();
闭包#2:
F()不再返回新函数,而是直接在函数体内创建一个新的全局函数inner()。
var inner;
var F = function(){
varb = "local variable";
varN = function(){
returnb;
};
inner= N;
}
此时,调用F()函数,则会创建一个新的函数N,并且将它赋值给全局变量inner。
F();
inner();
闭包#3:
该函数返回一个子函数,这个子函数返回的则是复函数的参数:
function F(param){
varN = function(){
returnparam;
}
param++;
returnN;
}
var inner = F(10);
inner();//11
于是我们知道,函数所绑定的是作用域本身,而不是在函数定义时,该作用域中的变量返回的值。
循环中的闭包:
来看一个三次的循环操作,在每次迭代中都会创建一个返回当前序列号的新函数,该函数会被添加到一个数组中并返回。
function F(){
vararr = [],i;
for(i=0;i<3;i++){
arr[i]=(function(x){
returnfunction(){
returnx;
}
}(i));
}
returnarr;
}
var arr = F();
arr[0]();
或者,不使用即时函数,将i的值本地化:
function F(){
functionbinder(x){
returnfunction(){
returnx;
}
}
vararr = [],i;
for(i=0;i<3;i++){
arr[i]= binder(i);
}
returnarr;
}
关于闭包的应用:
应用#1:
将私有变量保护起来:
var getValue,setValue;
(function(){
varsecret = 0;
getValue= function(){
returnsecret;
};
setValue= function(v){
if(typeofv === 'number'){
secret= v;
}
}
}());
getValue();
setValue(11);
getValue();//11
应用#2:(迭代器)
将下一个封装给易于使用的next()函数。
function setup(x){
vari = 0;
returnfunction(){
returnx[i++];
}
}
var next = setup(['a','b','c']);
next();
"a"
next()
"b"
next()
"c"
应用#3:
function makeSizer(size) {
returnfunction() {
document.body.style.fontSize= size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
document.getElementById('size-12').onclick= size12;
document.getElementById('size-14').onclick= size14;
document.getElementById('size-16').onclick= size16;
应用#4:
(模块模式,用闭包来定义公共函数,且其可以访问私有函数)
var Counter = (function(){
varprivateCounter = 0;
functionchangeBy(val){
privateCounter+= val;
}
return{
increment:function(){
changeBy(1);
},
decrement:function(){
changeBy(-1);
},
value:function(){
returnprivateCounter;
}
}
})();
console.log(Counter.value());
Counter.increment();
Counter.increment();
console.log(Counter.value());
Counter.decrement();
console.log(Counter.value());
- JavaScript闭包整理
- Javascript 闭包细节整理
- javascript的闭包closure整理
- 深入理解javascript闭包【整理】
- 关于javascript闭包--整理篇
- !!JavaScript中的作用域链和闭包 整理
- 前端重点知识整理(JavaScript)三:闭包
- 闭包——Javascript 进阶知识整理
- JavaScript学习笔记整理(八)闭包未完
- 【JavaScript】Javascript闭包
- 闭包整理
- 闭包--整理
- [整理]JavaScript闭包对象中定义常量和用取值器来获取常量值
- javascript的闭包javascript
- Javascript闭包演示javascript
- [ javascript ] javascript闭包测试!
- 【javascript】javascript中的闭包
- 【javascript】学习Javascript闭包
- Link Cut Tree 次探(升级版模板)
- Python Numpy
- vue指令以及dom操作
- php使用smtp类玩转电子邮件发送
- HTML之与浏览器交互, 表单标签
- JavaScript闭包整理
- 学习Spring Cloud第六课(将微服务注册到Eureka Server上)
- Python类定义、例化与调用
- [AFHTTPRequestSerializer requestWithMethod:URLString; 'Invalid parameter not satisfying: URLString'
- C++中 引用&与取地址&的区别
- sscanf函数用法
- oj1967: C/C++经典程序训练5---图形打印问题
- 【心得】写在创号之初
- 有父类的子类实例化时,子类与父类的成员变量,构造函数,代码块的执行顺序