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 相关文章推荐
jQuery让控件左右移动的三种实现方法
Sep 08 Javascript
JavaScript编程的10个实用小技巧
Apr 18 Javascript
php和js对数据库图片进行等比缩放示例
Apr 28 Javascript
详谈javascript中DOM的基本属性
Feb 26 Javascript
js与jquery正则验证电子邮箱、手机号、邮政编码的方法
Jul 04 Javascript
jQuery.form.js插件不能解决连接超时(timeout)的原因分析及解决方法
Oct 14 Javascript
如何使用bootstrap框架 bootstrap入门必看!
Apr 13 Javascript
微信小程序后台解密用户数据实例详解
Jun 28 Javascript
浅谈VUE监听窗口变化事件的问题
Feb 24 Javascript
js实现图片放大并跟随鼠标移动特效
Jan 18 Javascript
vue项目在webpack2实现移动端字体自适配功能
Jun 02 Javascript
原生JavaScript实现换肤
Feb 19 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
第十一节 重载 [11]
2006/10/09 PHP
php cache类代码(php数据缓存类)
2010/04/15 PHP
ThinkPHP 模板substr的截取字符串函数详解
2017/01/09 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
比较简单的一个符合web标准的JS调用flash方法
2007/11/29 Javascript
jValidate 基于jQuery的表单验证插件
2009/12/12 Javascript
30个精美的jQuery幻灯片效果插件和教程
2011/08/23 Javascript
javascript获得服务器端控件的ID的实现代码
2011/12/28 Javascript
让新消息在网页标题闪烁提示的jQuery代码
2013/11/04 Javascript
js子页面获取父页面数据示例
2014/05/15 Javascript
jQuery侧边栏实现代码
2016/05/06 Javascript
jQuery实现ajax的叠加和停止(终止ajax请求)
2016/08/08 Javascript
详解vue+vueRouter+webpack的简单实例
2017/06/17 Javascript
JS小球抛物线轨迹运动的两种实现方法详解
2017/12/20 Javascript
jQuery实现鼠标移到某个对象时弹出显示层功能
2018/08/23 jQuery
layui富文本编辑器前端无法取值的解决方法
2019/09/18 Javascript
JS实现可以用键盘方向键控制的动画
2020/12/11 Javascript
Django集成百度富文本编辑器uEditor攻略
2014/07/04 Python
跟老齐学Python之不要红头文件(1)
2014/09/28 Python
pyqt5使用按钮进行界面的跳转方法
2019/06/19 Python
阿里云ECS服务器部署django的方法
2019/08/29 Python
Python enumerate内置库用法解析
2020/02/24 Python
python+Selenium自动化测试——输入,点击操作
2020/03/06 Python
用CSS3绘制三角形的简单方法
2015/07/17 HTML / CSS
描述RIP和OSPF区别以及特点
2015/01/17 面试题
英文自我鉴定
2013/12/10 职场文书
装饰资料员岗位职责
2013/12/30 职场文书
家具厂厂长岗位职责
2014/01/01 职场文书
六一儿童节主持词
2014/03/21 职场文书
学生会副主席竞聘书
2014/03/31 职场文书
法人单位适用的授权委托书
2014/09/19 职场文书
劳模事迹材料范文
2014/12/24 职场文书
长城的导游词
2015/01/30 职场文书
课外活动总结
2015/02/04 职场文书
Python进行区间取值案例讲解
2021/08/02 Python
Nginx工作模式及代理配置的使用细节
2022/03/21 Servers