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 学习6 操纵元素显示效果的函数
Feb 07 Javascript
jQuery 顶部导航跟随滚动条滚动固定浮动在顶部
Jun 06 Javascript
一个不错的js html页面倒计时可精确到秒
Oct 22 Javascript
js实现最短的XML格式化工具实例
Mar 12 Javascript
JavaScript实现的SHA-1加密算法完整实例
Feb 02 Javascript
如何判断Javascript对象是否存在的简单实例
May 18 Javascript
jQuery简单实现彩色云标签效果示例
Aug 01 Javascript
快速解决js中window.location.href不工作的问题
Nov 02 Javascript
JavaScript设计模式之单例模式简单实例教程
Jul 02 Javascript
前端防止用户重复提交js实现代码示例
Sep 07 Javascript
基于jquery实现九宫格拼图小游戏
Nov 30 jQuery
详解vue路由篇(动态路由、路由嵌套)
Jan 27 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
收音机怀古---春雷3P7图片欣赏
2021/03/02 无线电
mac下使用brew配置环境的步骤分享
2011/05/23 PHP
PHP运行SVN命令显示某用户的文件更新记录的代码
2014/01/03 PHP
PHP入门教程之自定义函数用法详解(创建,调用,变量,参数,返回值等)
2016/09/11 PHP
thinkphp查询,3.X 5.0方法(亲试可行)
2017/06/17 PHP
CentOS7.0下安装PHP5.6.30服务的教程详解
2018/09/29 PHP
List Information About the Binary Files Used by an Application
2007/06/18 Javascript
JavaScript 异步调用框架 (Part 3 - 代码实现)
2009/08/04 Javascript
JavaScript 学习笔记一些小技巧
2010/03/28 Javascript
window.addEventListener来解决让一个js事件执行多个函数
2012/12/26 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(二)人物行走的实现
2013/01/23 Javascript
利用CSS、JavaScript及Ajax实现高效的图片预加载
2013/10/16 Javascript
Javascript中string转date示例代码
2013/11/01 Javascript
JS设置下拉列表框当前所选值的方法
2015/12/22 Javascript
AngularJS基础 ng-open 指令简单实例
2016/08/02 Javascript
AngularJS 执行流程详细介绍
2016/08/18 Javascript
JS使用正则表达式验证身份证号码
2017/06/23 Javascript
JS实现微信摇一摇原理解析
2017/07/22 Javascript
使用Vue 实现滑动验证码功能
2019/06/27 Javascript
微信小程序 导入图标实现过程详解
2019/10/11 Javascript
详解JavaScript中分解数字的三种方法
2021/01/05 Javascript
[03:07]【DOTA2亚洲邀请赛】我们,梦开始的地方
2017/03/07 DOTA
Python入门_学会创建并调用函数的方法
2017/05/16 Python
Python爬虫框架Scrapy实例代码
2018/03/04 Python
Python cookbook(数据结构与算法)从字典中提取子集的方法示例
2018/03/22 Python
Python判断变量名是否合法的方法示例
2019/01/28 Python
详解Python基础random模块随机数的生成
2019/03/23 Python
python读取目录下所有的jpg文件,并显示第一张图片的示例
2019/06/13 Python
Python 批量刷博客园访问量脚本过程解析
2019/08/30 Python
爱奇艺VIP会员:大剧抢先看
2018/07/11 全球购物
房地产项目策划书
2014/02/05 职场文书
访谈节目策划方案
2014/05/15 职场文书
校园环保标语
2014/06/13 职场文书
群众路线领导干部个人对照检查材料(集锦)
2014/09/23 职场文书
法定代表人身份证明书(含说明)
2014/10/02 职场文书
会议接待欢迎词范文
2015/01/26 职场文书