JavaScript 闭包的例子
例子出自<<JavaScript权威指南>>, 加上个人的理解和总结, 欢迎交流!
/*****************************************************************************/
/* 将一个立即调用函数的返回值赋给变量uniqueInteger
* 特点: 内部函数可以访问外部函数中的局部变量,当外部匿名函数立即调用返回之后, 除了返回的函数对象外
* 其他任何代码都无法访问私有变量counter, 实现了变量的隔离(相当于命名空间).
*/
var uniqueInteger = (function(){
var counter = ;
return function(){
return counter++;
};
}());
/*****************************************************************************/ /*****************************************************************************/
/* 多个嵌套函数共享一个私有变量
*/
function counter(){
var n = ;
return {
count: function(){
return n++;
},
reset: function(){
n = ;
}
};
}
var c = counter(); // 相当于上一个例子中的立即调用, 只是得到的是一个直接对象, 而不是函数对象
var d = counter(); // 定义了另一个对象. 和c各自独立.
// 两个对象各自维护自己的私有变量 n , 其他外部代码不能再直接访问它们的 n 的值.
console.log(c.count()); //0
console.log(c.count()); //1
c.reset();
console.log(c.count()); //0
d.count(); d.reset();
//上面的counter()也可以类似如下实现, 因为参数和局部变量一样保存在作用域链中.
function counter2(n){
n = n || ;
return {
get count(){return n++;},
set count(m){
if(m >= n) n = m;
else throw Error("count can only be set to a larger value");
}
};
}
var e = counter2();
e.count;
console.log(e.count); // 11
e.count = ;
console.log(e.count); // 20
console.log(e.count); // 21
/*****************************************************************************/ /*****************************************************************************/
/* 利用闭包实现私有属性存取器方法
* 为传入的某个对象加入setter和getter方法, 但是setter/getter方法操作的属性并没有添加到
* 对象 o 中, 而是由闭包代为保管!
* 这样只能通过setter/getter进行访问, 其他地方无法直接访问,成为私有变量.
*/
function addPrivateProperty(o,name,predicate){
var value;
o['get'+name] = function(){
return value;
},
o['set'+name] = function(v){
if(predicate && !predicate(v))
throw Error("set"+name+":invalid value "+v);
else
value = v;
};
}
var o = {};
addPrivateProperty(o,"Name",function(x){return typeof(x) == "string";});
o.setName("roger");
console.log(o.getName()); // roger
/*****************************************************************************/ /*****************************************************************************/
/* 当多个闭包共享同样的私有变量或变量时要注意作用域时动态变化的.
* 嵌套的函数不会讲作用域内的私有成员复制一份(只是引用), 也不会对所绑定的变量生成静态快照.
*/
function constfunc(v){
return function(){
return v;
};
}
var funcs = [];
for(var i=;i<;++i){
// 创建多个闭包共享变量 i.作用域链在变化,直到循环结束, 但是执行constfunc时保存了i的状态.
funcs[i] = constfunc(i);
}
console.log(funcs[]()); // 5
function constfunc2(){
var funcs = [];
for(var i=;i<;++i){
//函数对象并没有保存i的状态, 在外面调用时作用域的状态已经变化了, 和预期不一样.
//因为内嵌对象不会将作用域内的私有成员复制一份(只是一份引用而已)
funcs[i] = function(){
return i;
};
}
return funcs;
}
var funcs = constfunc2();
console.log(funcs[]()); //10
function constfunc3(){
var funcs = [];
for(var i=;i<;++i){
funcs[i] = (function(){
return i;
}()); //使用函数立即调用, 直接将闭包的状态保存在了funcs[i]中.
}
return funcs;
}
var funcs = constfunc3();
console.log(funcs[]); // 5
/*****************************************************************************/ /*****************************************************************************/
/*需要注意this和arguments
1. this不是变量, 而是关键字, 会随着作用域而变化
2. arguments是函数在调用时引擎自动创建的变量, 也是随作用域而变化的
解决方法: 将外部函数的this和arguments的内容(而不是引用)保存到局部变量中,
从而避免作用域变化带来的不确定性
*/
-->
JavaScript 闭包的例子的更多相关文章
- javascript闭包学习例子
javascript中的闭包个很让人头疼的概念.总结一下 闭包是指有权访问一个函数作用域中的变量的函数.创建闭包最常见的方式,是在一个函数内部创建另一个函数,用return返回出去. 使用闭包可能造成 ...
- javascript 闭包理解例子
function Jquery(){ this.name = 'ysr'; this.sex = 'man'; return { x: this, age : 26 } } var b = new J ...
- 《Web 前端面试指南》1、JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- javascript闭包和作用域链
最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...
- JavaScript闭包模型
JavaScript闭包模型 ----- [原创翻译]2016-09-01 09:32:22 < 一> 闭包并不神秘 本文利用JavaScript代码来阐述闭包,目的是为了使普通 ...
- javascript 闭包(转)
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- 最简明的JavaScript闭包解释
最简明的JavaScript闭包解释 JavaScript是这几年最火的编程语言之一,从前端到服务器端,再到脚本,好像没有一个地方没有JavaScript的身影.这个世界上任何的一种事物的存在必然有其 ...
- JavaScript闭包的底层运行机制
转自:http://blog.leapoahead.com/2015/09/15/js-closure/ 我研究JavaScript闭包(closure)已经有一段时间了.我之前只是学会了如何使用它们 ...
随机推荐
- WindowBrush
m_Element.Fill = SystemColors.WindowBrush; BorderBrush="{x:Static SystemColors.WindowBrush}&quo ...
- gvim下用Vundle安装solarized主题的方法
1.在.vimrc中加入 Bundle 'Solarized' 2.重启gvim,并执行 :BundleInstall 3.将solarized.vim文件放入.vim下的colors文件夹内(如果没 ...
- RabbitMQ-从基础到实战(4)— 消息的交换(中)
转自:https://www.cnblogs.com/4----/p/6590459.html 1.简介 本章节和官方教程相似度较高,英文好的可以移步官方教程 在上一章的例子中,我们创建了一个消费者, ...
- 字符串和JSON对象互转的方法
采用Ajax的项目开发过程中,经常需要将JSON格式的字符串返回到前端,前端解析成JS对象(JSON ).字符串转JSON对象 1.eval方式解析.function strToJson(str){ ...
- mysql数据库复制
核心命令是 myssqldump mysqldump --host=host1 --opt sourceDb| mysql --host=host2 -C targetDb 详情参考: MySQL数据 ...
- XE4 TStringDynArray 比 c6 的TStringList 好用 字符串 分解 分割 转换 TByteDynArray
TStringDynArray 动态数组 字符串 分解 分割 System::DynamicArray<System::UnicodeString> TByteDynArray, ...
- Windows下MySQL5.6查找my.ini配置文件
在DOS命令行窗口登录MySQL,输入如下命令查看MySQL的安装目录和数据存放目录,MySQL的配置文件就在数据存放目录下: 另外一种方法: 在"开始 → 所有程序 → MySQL&quo ...
- 使用.htaccess文件
禁止对无索引文件的目录进行文件列表展示 默认情况下,当我们访问网站的某个无索引文件(如index.html,index.htm或 index.php)目录时,服务器会显示该目录的文件和子目录列表,这是 ...
- Simple2D-23(重构)反走样几何图形
以前 Simple2D 使用 Canvas2D 对象来绘制几何图形,而且渲染出来的几何图形存在明显的锯齿.如果想要抗锯齿的几何图形,则需要开启 OpenGL 的 MSAA,这需要很大的开销. 如果不使 ...
- ios App 文件夹
转:http://stackoverflow.com/questions/16561779/nssearchpathfordirectoriesindomains-nsuserdomainmask D ...