提到闭包,想必大家都早有耳闻,下面说下我的简单理解。
平时写代码、第三方框架和组件都或多或少用到了闭包。
所以,了解闭包是非常必要的。呵呵...

一、什么是闭包
简而言之,就是能够读取其他函数内部变量的函数。
由于JS变量作用域的特性,外部不能访问内部变量,内部可以外部变量。

二、使用场景
1. 实现私有成员。
2. 保护命名空间,避免污染全局变量。
3. 缓存变量。

先看一个封装的例子:

var person = function () {
// 变量作用域为函数内部,外部无法访问
var name = "default"; return {
getName: function () {
return name;
},
setName: function (newName) {
name = newName;
}
}
}(); console.log(person.name); // 直接访问,结果为:undefined
console.log(person.getName()); // 结果为:default
console.log(person.setName("langjt"));
console.log(person.getName()); // 结果为:langjt

再看循环中常用闭包解决引用外部变量问题:

var aLi = document.getElementsByTagName('li');
for (var i=0, len=aLi.length; i<len; i++) {
aLi[i].onclick = function() {
alert(i); // 无论点击哪个<li>元素,弹出的值都为len,表明这里的i和在for之后打印i的值是一样的。
};
}

使用闭包后:

var aLi = document.getElementsByTagName('li');
for (var i=0, len=aLi.length; i<len; i++) {
aLi[i].onclick = (function(i) {
return function() {
alert(i); // 此时点击<li>元素,就会弹出对应的下标了。
}
})(i);
}

三、注意事项
1. 内存泄漏
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题。
比如:

function foo() {
var oDiv = document.getElementById(‘J_DIV’);
var id = oDiv.id;
oDiv.onclick = function() {
// alert(oDiv.id); 这里存在循环引用,IE低版本页面关闭后oDiv仍在内存中。所以尽可能缓存基本类型而不是对象。
alert(id);
};
oDiv = null;
}

2. 变量命名
如果内部函数的变量和外部函数的变量名相同时,那么内部函数再也无法指向外部函数那个同名的变量。
比如:

function foo(num) {
return function(num) {
console.log(num);
}
}
var f = new foo(9);
f(); // undefined

其实上面的用法,专业术语叫函数柯里化(Currying),就是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。本质上也利用了闭包可以缓存的特性,比如:

var adder = function(num) {
return function(y) {
return num+y;
};
}; var inc = adder(1);
var dec = adder(-1);
//inc, dec现在是两个新的函数,作用是将传入的参数值 (+/‐)1
alert(inc(99));//
alert(dec(101));//100
alert(adder(100)(2));//102
alert(adder(2)(100));//

再比如阿里玉伯的seaJS源码中:

/**
* util-lang.js - The minimal language enhancement
*/
function isType(type) {
return function(obj) {
return {}.toString.call(obj) == "[object " + type + "]"
}
} var isObject = isType("Object");
var isString = isType("String");

Javascript闭包简单理解的更多相关文章

  1. 对JavaScript闭包的理解

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 在开始了解闭包前我们必须要先理解JavaScript的变量作用域. 一.变量的作用域无非就是两 ...

  2. javascript闭包的理解

    闭包是Javascript的一个难点,但也是一个很重要的知识点. 1.首先我们要知道变量作用域链 变量的作用域分两种:全局变量和局部变量.没有定义到任何函数中的变量为全局变量,在函数中定义的变量为局部 ...

  3. 我对 javascript 闭包的理解

    学js的学到闭包,但是理解不深. 后来看了一下这篇文章: 地址:http://leepiao.blog.163.com/blog/static/4850313020112835355917/ 内容如下 ...

  4. JavaScript闭包简单应用

    闭包定义 在JavaScript中,当一个内部函数被其外部函数之外的变量引用时,就形成了一个闭包.简单说,闭包就是能够读取其他函数内部变量的函数. 闭包的作用: 1. 可以读取函数内部的变量 2. 让 ...

  5. javascript 闭包的理解(一)

    过很多谈如何理解闭包的方法,但大多数文章,都是照抄或者解释<Javascript高级程序设计(第三版)>对于闭包的讲解,甚至例程都不约而同的引用高程三181页‘闭包与变量’一节的那个“返回 ...

  6. javascript闭包的理解和实例

    所谓闭包,值得是词法表示包括不必要计算的变量的函数,也就是说,该函数可以使用函数外定义的变量. 顺便提示一下: 词法作用域:变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通 ...

  7. 关于Javascript 闭包的理解

    一.什么是闭包? 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.相信很少有人能直接看懂这句话,因为他描述的太学术.其实这句话 ...

  8. 关于Javascript闭包的理解

    以下内容属个人理解,如有看不明白或漏洞之处,纯属水平不佳,还望见谅. 关于闭包,高程里的定义是:指有权访问另一个函数作用域中的变量的函数.创建闭包最常见的方法就是在一个函数的内部再创建一个函数. 这里 ...

  9. python 装饰器、内部函数、闭包简单理解

    python内部函数.闭包共同之处在于都是以函数作为参数传递到函数,不同之处在于返回与调用有所区别. 1.python内部函数 python内部函数示例: def test(*args): def a ...

随机推荐

  1. LINUX HA:Pacemaker + Corosync初配成功

    参考很多文档: http://zhumeng8337797.blog.163.com/blog/static/100768914201218115650522/ 下一步,想想这个PC组和与HAPROX ...

  2. 通过CreateOleObject控制IE

    //第二种方法可以有更多控制procedure TForm1.Button1Click(Sender: TObject);procedure OpenInIE(aURL: string);//need ...

  3. 使用NetUserAdd API函数创建远程用户

    http://apps.hi.baidu.com/share/detail/33407620 使用NetUserAdd编程创建远程用户Windows API NetUserAdd()可以创建Windo ...

  4. php socket 通信

    Socket扩展是基于流行的BSD sockets,实现了和socket通讯功能的底层接口,它可以和客户端一样当做一个socket服务器. 想了解更通用的客户端socket接口,请看 stream_s ...

  5. phpMyAdmin <= 4.0.4.1 import.php GLOBALS变量注入漏洞

    漏洞版本: phpMyAdmin <= 4.0.4.1 漏洞描述: CVE(CAN) ID: CVE-2013-4729 phpmyadmin是MySQL数据库的在线管理工具,主要功能包括在线创 ...

  6. App自动更新之通知栏下载

    见证过博客园的多次升级,你也希望你的软件通过更新发布新特性通知用户吧,是的.这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用. 1.设计思路,使用Versio ...

  7. 从SG函数浅谈解决博弈问题的通法

    基于笔者之前对于几种二元零和博弈游戏的介绍,这里将其思想进行简单的提炼,并引出解决这类二元零和博弈游戏的强大工具——SG函数. 其实对于博弈游戏如Bash.Nim等基本类型,异或一些比较高级的棋类游戏 ...

  8. poj 2187 凸包加旋转卡壳算法

    题目链接:http://poj.org/problem?id=2187 旋转卡壳算法:http://www.cppblog.com/staryjy/archive/2009/11/19/101412. ...

  9. Windows下svn客户端和服务器的安装使用

    svn,全称subversion, 是目前用的较多的开源的版本管理工具.相信有些经历的程序员应该都听说过它. 通常的svn服务器是搭建在Linux中,不过如果作为个人或者单个小组使用的话,就可以把sv ...

  10. mysql group by的用法 注意

    group by 用法: 官方的解释:select 后面的字段必须出现在 group by 后面, 除非是聚合,sum,或者count 但是如果 是多表联查, SELECT    c.`name` A ...