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

一、什么是闭包
简而言之,就是能够读取其他函数内部变量的函数。
由于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. 这十大MCU厂商瓜分着中国市场

    MCU(Micro Control Unit)中文名称为微控制单元,又称单片微型计算机(Single Chip Microcomputer)或者单片机,是指随着大规模集成电路的出现及其发展,将计算机的 ...

  2. linux 发布 qt(更新ld命令的路径依赖)

    PATH 错误解决error while loading shared libraries: libXXX.so.X: cannot open shared object file: No such ...

  3. Delphi重载,覆盖,多态

    一.override 重载 type TFigure = class procedure Draw; virtual;//(我的理解是)父类中可以使用父类的,子类中使用子类的.与“四”是有区别的. e ...

  4. 深入浅出 Java Concurrency (1) : J.U.C的整体认识

    转 http://www.blogjava.net/xylz/archive/2010/06/30/324915.html 去年年底有一个Guice的研究计划,可惜由于工作“繁忙”加上实际工作中没有用 ...

  5. Strange Way to Express Integers (一般模线性方程组)

    Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 8476   Accepted: 2554 Description Elin ...

  6. HDU 5875 Function 【倍增】 (2016 ACM/ICPC Asia Regional Dalian Online)

    Function Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  7. Eclipse集成环境中Android SDK下载及更新失败解决方案

    由于公司新项目比较忙,有好长一段时间没碰Android开发咯! 近期闲来在网上下了个开源的应用想拿来自己学习下其中的源码及整体设计,当我把下下来的项目导入Eclipse中时,报如下警告: 原因是我本地 ...

  8. OpenStack简单测试性能监控数据记录

  9. 十大纺织品、布料、面料品牌排名 - 十大品牌 - 中国品牌网 Chinapp.com

    十大纺织品.布料.面料品牌排名 - 十大品牌 - 中国品牌网 Chinapp.com 十大纺织品.布料.面料品牌排名

  10. Spring 基础知识

    Spring架构简单描述 原文:https://www.shiyanlou.com/courses/document/212 Spring 概述 1. Spring 是什么 Spring是一个开源的轻 ...