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 相关文章推荐
javascript 树形导航菜单实例代码
Aug 13 Javascript
jquery text(),val(),html()方法区别总结
Nov 04 Javascript
jQuery验证元素是否为空的两种常用方法
Mar 17 Javascript
Javascript中的getUTCHours()方法使用详解
Jun 10 Javascript
JavaScript类型检测之typeof 和 instanceof 的缺陷与优化
Jan 13 Javascript
遍历js中对象的属性和值的实例
Nov 21 Javascript
关于Node.js的events.EventEmitter用法介绍
Apr 01 Javascript
js实现手机web图片左右滑动效果
Dec 29 Javascript
微信小程序云开发之云函数详解
May 16 Javascript
微信小程序云开发 搭建一个管理小程序
May 17 Javascript
微信小程序中如何计算距离某个节日还有多少天
Jul 15 Javascript
JS实现简易贪吃蛇游戏
Aug 24 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
手把手教你使用DedeCms的采集的图文教程
2007/03/11 PHP
PHP中的事务使用实例
2015/05/26 PHP
PHP ajax+jQuery 实现批量删除功能实例代码小结
2018/12/06 PHP
安装PHP扩展时解压官方 tgz 文件后没有configure文件无法进行配置编译的问题
2020/08/26 PHP
JS打开图片另存为对话框实现代码
2012/12/26 Javascript
hover的用法及live的用法介绍(鼠标悬停效果)
2013/03/29 Javascript
浅谈jQuery中的事件
2015/03/23 Javascript
JS实现霓虹灯文字效果的方法
2015/08/06 Javascript
浅谈JavaScript中的string拥有方法的原因
2015/08/28 Javascript
AngularJS自动表单验证
2016/02/01 Javascript
js 获取元素所有兄弟节点的实现方法
2016/09/06 Javascript
Angular.js中处理页面闪烁的方法详解
2017/03/09 Javascript
node+koa实现数据mock接口的方法
2017/09/20 Javascript
微信小程序实现时间预约功能
2018/11/27 Javascript
vue实现的上拉加载更多数据/分页功能示例
2019/05/25 Javascript
JavaScript 格式化数字、金额、千分位、保留几位小数、舍入舍去
2019/07/23 Javascript
layui-table表复选框勾选的所有行数据获取的例子
2019/09/13 Javascript
es6数组之扩展运算符操作实例分析
2020/04/25 Javascript
JavaScript代码模拟鼠标自动点击事件示例
2020/08/07 Javascript
Python中的Descriptor描述符学习教程
2016/06/02 Python
python中实现延时回调普通函数示例代码
2017/09/08 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
2018/02/10 Python
python数据结构之线性表的顺序存储结构
2018/09/28 Python
python命令行工具Click快速掌握
2019/07/04 Python
django中上传图片分页三级联动效果的实现代码
2019/08/30 Python
Python3.9新特性详解
2020/10/10 Python
给儿子的表扬信
2014/01/15 职场文书
劲霸男装广告词
2014/03/21 职场文书
导师工作推荐信范文
2014/05/17 职场文书
优秀实习生主要事迹
2014/05/29 职场文书
纺织工程专业推荐信
2014/09/08 职场文书
2014年监理个人工作总结
2014/12/11 职场文书
租赁协议书
2015/01/27 职场文书
小学生五一劳动节演讲稿
2015/03/18 职场文书
普通员工辞职信范文
2015/05/12 职场文书
校长新学期寄语2016
2015/12/04 职场文书