Javascript闭包用法实例分析


Posted in Javascript onJanuary 23, 2015

本文实例分析了Javascript闭包的概念及用法。分享给大家供大家参考。具体如下:

提到闭包,想必大家都早有耳闻,下面说下我的简单理解。
说实话平时工作中实际手动写闭包的场景并不多,但是项目中用到的第三方框架和组件或多或少用到了闭包。
所以,了解闭包是非常必要的。呵呵...

一、什么是闭包

简而言之,就是能够读取其他函数内部变量的函数。
由于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));//100

alert(dec(101));//100 

alert(adder(100)(2));//102 

alert(adder(2)(100));//102

再比如阿里玉伯的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程序设计有所帮助。

Javascript 相关文章推荐
Open and Print a Word Document
Jun 15 Javascript
HTML中Select不用Disabled实现ReadOnly的效果
Apr 07 Javascript
js URL参数的拼接方法比较
Feb 15 Javascript
JS左右无缝滚动(一般方法+面向对象方法)
Aug 17 Javascript
document.createElement()用法
Mar 13 Javascript
jquery hover 不停闪动问题的解决方法(亦为stop()的使用)
Feb 10 Javascript
脚本div实现拖放功能(两种)
Feb 13 Javascript
Js自定义多选框效果的实例代码
Jul 05 Javascript
使用 Javascript 实现浏览器推送提醒功能的示例
Nov 03 Javascript
解决bootstrap中下拉菜单点击后不关闭的问题
Aug 10 Javascript
js+springMVC 提交数组数据到后台的实例
Sep 21 Javascript
vue-cli4使用全局less文件中的变量配置操作
Oct 21 Javascript
JavaScript学习笔记之Function对象
Jan 22 #Javascript
JavaScript学习笔记之Cookie对象
Jan 22 #Javascript
javascript二维数组转置实例
Jan 22 #Javascript
JavaScript学习笔记之内置对象
Jan 22 #Javascript
JavaScript学习笔记之JS事件对象
Jan 22 #Javascript
jquery实现搜索框常见效果的方法
Jan 22 #Javascript
JavaScript学习笔记之定时器
Jan 22 #Javascript
You might like
php权重计算方法代码分享
2014/01/09 PHP
PHP实现根据设备类型自动跳转相应页面的方法
2014/07/24 PHP
PHP中round()函数对浮点数进行四舍五入的方法
2014/11/19 PHP
PHP内置的Math函数效率测试
2014/12/01 PHP
PHP查询快递信息的方法
2015/03/07 PHP
在Win2003(64位)中配置IIS6+PHP5.2.17+MySQL5.5的运行环境
2016/04/04 PHP
jquery Moblie入门—hello world的示例代码学习
2013/01/08 Javascript
刷新页面的几种方法小结(JS,ASP.NET)
2014/01/07 Javascript
JS将所有对象s的属性复制给对象r(原生js+jquery)
2014/01/25 Javascript
js使用for循环查询数组中是否存在某个值
2014/08/12 Javascript
jQuery插件bxSlider实现响应式焦点图
2015/04/12 Javascript
javascript实现的固定位置悬浮窗口实例
2015/04/30 Javascript
JS实现简单易用的手机端浮动窗口显示效果
2016/09/07 Javascript
详解angularJs中自定义directive的数据交互
2017/01/13 Javascript
浅谈Angular 的变化检测的方法
2018/03/01 Javascript
js中获取URL参数的共用方法getRequest()方法实例详解
2018/10/24 Javascript
如何用JS模拟实现数组的map方法
2020/07/30 Javascript
如何解决django配置settings时遇到Could not import settings 'conf.local'
2014/11/18 Python
Python 私有函数的实例详解
2017/09/11 Python
numpy matrix和array的乘和加实例
2018/06/28 Python
Windows下将Python文件打包成.EXE可执行文件的方法
2018/08/03 Python
用Pycharm实现鼠标滚轮控制字体大小的方法
2019/01/15 Python
Python实现DDos攻击实例详解
2019/02/02 Python
python基于gevent实现并发下载器代码实例
2019/11/01 Python
python实现凯撒密码、凯撒加解密算法
2020/06/11 Python
Python实现淘宝秒杀功能的示例代码
2021/01/19 Python
Nuts.com:优质散装,批发坚果、干果和巧克力等
2017/03/21 全球购物
波比布朗英国官网:Bobbi Brown英国
2017/11/13 全球购物
泰国国际航空公司官网:Thai Airways International
2019/12/04 全球购物
eBay美国官网:eBay.com
2020/10/24 全球购物
医疗器械售后服务承诺书
2014/05/21 职场文书
机关中层领导干部群众路线教育实践活动个人对照检查材料
2014/09/24 职场文书
求职信范文怎么写
2015/03/19 职场文书
525心理健康活动总结
2015/05/08 职场文书
Laravel中获取IP的真实地理位置
2021/04/01 PHP
tp5使用layui实现多个图片上传(带附件选择)的方法实例
2021/11/17 PHP