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 相关文章推荐
基于prototype的validation.js发布2.3.4新版本,让你彻底脱离表单验证的烦恼
Dec 06 Javascript
jQuery 浮动导航菜单适合购物商品类型的网站
Sep 09 Javascript
Jquery+Ajax+PHP+MySQL实现分类列表管理(下)
Oct 28 Javascript
利用jQuery实现WordPress中@的ID悬浮显示评论内容
Dec 11 Javascript
js实现的下拉框二级联动效果
Apr 30 Javascript
Bootstrap导航条学习使用(一)
Feb 08 Javascript
最常用的jQuery表单验证(简单)
May 23 jQuery
浅谈struts1 &amp; jquery form 文件异步上传
May 25 jQuery
javascript写一个ajax自动拦截并下载数据代码实例
Sep 07 Javascript
vue实现简单学生信息管理
May 30 Javascript
原生JS实现九宫格抽奖
Sep 13 Javascript
解决vue 使用axios.all()方法发起多个请求控制台报错的问题
Nov 09 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基于socket实现的简单客户端和服务端通讯功能示例
2017/07/10 PHP
阿里对象存储OSS在laravel框架中的使用方法
2019/10/13 PHP
jquery下jstree简单应用 - v1.0
2011/04/14 Javascript
javascript改变position值实现菜单滚动至顶部后固定
2013/01/18 Javascript
js实现倒计时(距离结束还有)示例代码
2013/07/24 Javascript
JQuery实现table行折叠效果以JSON做数据源
2014/05/26 Javascript
javascript学习笔记(四)function函数部分
2014/09/30 Javascript
jQuery制作拼图小游戏
2015/01/12 Javascript
JS简单实现无缝滚动效果实例
2016/08/24 Javascript
angularjs实现下拉列表的选中事件示例
2017/03/03 Javascript
使用jQuery监听扫码枪输入并禁止手动输入的实现方法(推荐)
2017/03/21 jQuery
如何通过非数字与字符的方式实现PHP WebShell详解
2017/07/02 Javascript
vue轮播图插件vue-concise-slider的使用
2018/03/13 Javascript
vue列表数据发生变化指令没有更新问题及解决方法
2020/01/16 Javascript
[03:16]DOTA2完美大师赛主赛事首日集锦
2017/11/23 DOTA
Python读取键盘输入的2种方法
2015/06/16 Python
解决已经安装requests,却依然提示No module named requests问题
2018/05/18 Python
Python迭代器与生成器基本用法分析
2018/07/26 Python
Python实现去除列表中重复元素的方法总结【7种方法】
2019/02/16 Python
Python-Seaborn热图绘制的实现方法
2019/07/15 Python
Python爬虫requests库多种用法实例
2020/05/28 Python
python3排序的实例方法
2020/10/20 Python
解决html5中的video标签ios系统中无法播放使用的问题
2020/08/10 HTML / CSS
英国精品买手店:Browns Fashion
2016/09/29 全球购物
英国信箱在线鲜花速递公司:Bloom & Wild
2019/03/10 全球购物
Bugatchi官方网站:男士服装在线
2019/04/10 全球购物
工商学院毕业生自荐信
2013/11/12 职场文书
学前教育学生自荐信范文
2013/12/31 职场文书
校外活动方案
2014/08/28 职场文书
诉讼授权委托书
2014/10/15 职场文书
学生考试舞弊检讨书
2015/01/01 职场文书
2015年助理工程师工作总结
2015/04/03 职场文书
证劵公司反洗钱宣传活动总结
2015/05/08 职场文书
安全生产感想
2015/08/07 职场文书
优质护理服务心得体会
2016/01/22 职场文书
干部作风纪律整顿心得体会
2016/01/23 职场文书