JavaScript中闭包之浅析解读
JavaScript中的闭包真心是一个老生常谈的问题了,,其实我们在做项目时候,其实就经常用到闭包的,可是面试问的时候,回答又往往是我们经常搜到的答案,唉 不管是应付面试 还是真的想学点东西 ,我也用自己的理解跟大家分享一下,书面化就避免不了了的。
1.闭包是什么?
红宝书中曰:“是指有权访问另外一个函数作用域中的变量的函数。”
简单的说,JavaScript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。再通俗的说就是“一个函数内部创建另外一个函数,后面这个函数可以读取上面那个函数中的变量,后面这个函数就可以称作‘闭包’”。
2.闭包有啥用?
通过我大量的查阅,如果说“通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率”,会不会感觉很空洞,那这些会不会好一些,由于在JavaScript中没有真正的块级作用域,但是为了给某个函数声明一些只有该函数才能使用的局部变量时,我们就会用到闭包,这样我们可以很大程度上减少全局作用域中的变量,净化全局作用域。
下面举例说明一下:
1.匿名自执行函数
我们知道所有的变量,如果不加上var关键字,则默认的会添加到全局对象的属性上去,这样的临时变量加入全局对象有很多坏处,
var data= {
table : [],
tree : {}
};
(function(dm){
for(var i = 0; i < dm.table.rows; i++){
var row = dm.table.rows[i];
for(var j = 0; j < row.cells; i++){
drawCell(i, j);
}
}
})(data);
我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在函数执行完后会立刻释放资源,关键是不污染全局对象。
2.结果缓存
我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
var CachedSearchBox = (function(){
var cache = {},
count = [];
return {
attachSearchBox : function(dsid){
if(dsid in cache){//如果结果在缓存中
return cache[dsid];//直接返回缓存中的对象
}
var fsb = new uikit.webctrl.SearchBox(dsid);//新建
cache[dsid] = fsb;//更新缓存
if(count.length > 100){//保正缓存的大小<=100
delete cache[count.shift()];
}
return fsb;
},
clearSearchBox : function(dsid){
if(dsid in cache){
cache[dsid].clearSelection();
}
}
};
})();
CachedSearchBox.attachSearchBox("input");
这样我们在第二次调用的时候,就会从缓存中读取到该对象。
3.封装
var person = function(){
//变量作用域为函数内部,外部无法访问
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();
print(person.name);//直接访问,结果为undefined
print(person.getName());
person.setName("abruzzi");
print(person.getName());
4.实现类和继承
function Person(){
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
};
var p = new Person();
p.setName("Tom");
alert(p.getName());
var Jack = function(){};
//继承自Person
Jack.prototype = new Person();
//添加私有方法
Jack.prototype.Say = function(){
alert("Hello,my name is Jack");
};
var j = new Jack();
j.setName("Jack");
j.Say();
alert(j.getName());
写到最后,不知道最后各位亲们发现 自己曾经做过的项目中其实用到过很多这种,反正我是遇到了,闭包就是这么一直存在着的。
关于闭包,虽然老生常谈,但是还是挺重要的。至于闭包的缺陷嘛,就说一个好了 不是干货 滥用闭包 ,会导致内存泄漏,内存泄漏是啥 自己百度吧 ^_^。
谢谢各位道友能看到最后,希望大家都能顺顺心心。
JavaScript中闭包之浅析解读的更多相关文章
- 在Javascript中闭包(Closure)
在Javascript中闭包(Closure) 什么是闭包 “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. ...
- javascript中闭包最简单的简绍
javascript中闭包是什么 JavaScript 变量可以是局部变量或全局变量.私有变量可以用到闭包.闭包就是将函数内部和函数外部连接起来的一座桥梁. 函数的闭包使用场景:比如我们想要一个函数来 ...
- 在JavaScript中闭包的作用和简单的用法
在JavaScript中闭包的作用和简单的用法 一.闭包的简介 作用域链:在js中只有函数有作用域的概念,由于函数内能访问函数外部的数据,而函数外部不能访问函数内部的数据,由上述形成一种作用域访问的链 ...
- 关于javascript中闭包的理解
闭包就是能够读取其他函数内部变量的函数. 在javascript中,只有函数内部的子函数可以读取局部变量,因此,我理解闭包就是定义在一个函数内部的函数. 例子: var f1 = function() ...
- 浅谈JavaScript中闭包
引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...
- javascript中闭包的概念
这个是每个前端工程师绕不开的一个问题,网上各种资料很多,整个春节,我仔细研读了红皮经典中关于这一块的注释,加深了对这一块的理解. 有好几个概念需要重申一下.以下都是我的理解: 1. 闭包是javasc ...
- Javascript中闭包的作用域链
作用域定义了在当前上下文中能够被访问到的成员,在Javascript中分为全局作用域和函数作用域,通过函数嵌套可以实现嵌套作用域. 闭包一般发生在嵌套作用域中.闭包是JavaScript最强大的特性之 ...
- JavaScript中闭包实现的私有属性的getter()和setter()方法
注意: 以下的输出都在浏览器的控制台中 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
- JavaScript 中 闭包 的详解
闭包是什么 在 JavaScript 中,闭包是一个让人很难弄懂的概念.ECMAScript 中给闭包的定义是:闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量. ...
随机推荐
- Node.js之NPM工具使用
1.NPM介绍:包管理工具 (1)允许用户从NPM服务器下载别人编写的第三方包到本地石使用 (2)允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用 (3)允许用户将自己编写的包或命令行程 ...
- 苹果手机微信上form表单提交的问题
场景:前端页面请求后端php,返回带form表单dom元素,然后将其追在页面上,返回的html字段中包含表单自动提交的代码,想法是将带有表单自动提交的dom元素追加到页面上,然后表单自动提交到另外一个 ...
- 15分钟学会Lua
lua的很多语法跟matlab很像 最基本的赋值是一样的 循环和选择判断后面必须跟一个关键字:do和then ,, do ... end if - then - end table是lua的唯一一种数 ...
- Codeforces Round #361 (Div. 2) A
A - Mike and Cellphone Description While swimming at the beach, Mike has accidentally dropped his ce ...
- node、npm、gulp、bower、ionic下载及安装
node: http://nodejs.cn/ npm: 随node一起安装了 gulp: http://www.gulpjs.com.cn/docs/getting-started/ bower: ...
- 配置Spark on YARN集群内存
参考原文:http://blog.javachen.com/2015/06/09/memory-in-spark-on-yarn.html?utm_source=tuicool 运行文件有几个G大,默 ...
- linux ping加执行时间
[root@back_zabbix_100 ~]# ping 10.10.30.250 | awk '{print $0"\t" strftime("%H:%M:%S&q ...
- CSS 页面顶部阴影和给浏览器强制加上滚动条
/*给浏览器强制加上滚动条*/ html{height: 101%;} /*页面顶部阴影*/ body:before{ content: ""; position: fixed; ...
- MYSQL MHA
MYSQL MHA 简介: MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于 Face ...
- sql编写将时间转换年月日 时分格式
SELECT SUBSTRING(CONVERT(varchar(100),时间字段, 22),0,15) AS aa FROM 表名