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 相关文章推荐
js url传值中文乱码之解决之道
Nov 20 Javascript
jcarousellite.js 基于Jquery的图片无缝滚动插件
Dec 30 Javascript
ASP.NET jQuery 实例12 通过使用jQuery validation插件简单实现用户注册页面验证功能
Feb 03 Javascript
浅谈Javascript事件模拟
Jun 27 Javascript
JQuery入门——事件切换之toggle()方法应用介绍
Feb 05 Javascript
JS取request值以及自动执行使用示例
Feb 24 Javascript
js实现浏览本地文件并显示扩展名的方法
Aug 17 Javascript
Node.js巧妙实现Web应用代码热更新
Oct 22 Javascript
浅谈JavaScript 覆盖原型以及更改原型
Aug 31 Javascript
vue ssr 指南详读
Jun 29 Javascript
脚手架vue-cli工程webpack的作用和特点
Sep 29 Javascript
微信小程序局部刷新触发整页刷新效果的实现代码
Nov 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
DC《神奇女侠2》因疫情推迟上映 温子仁新恐怖片《恶性》撤档
2020/04/09 欧美动漫
自定义PHP分页函数
2006/10/09 PHP
PHP获得用户使用的代理服务器ip即真实ip
2006/12/31 PHP
HTML5如何适配 iPhone IOS 底部黑条
2021/03/09 HTML / CSS
JavaScript类型转换方法及需要注意的问题小结(挺全面)
2010/11/11 Javascript
利用JS进行图片的切换即特效展示图片
2013/12/03 Javascript
jsPDF导出pdf示例
2014/05/02 Javascript
js实现字符串转日期格式的方法
2015/05/20 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
2016/05/20 Javascript
JavaScript 弹出子窗体并返回结果到父窗体的实现代码
2016/05/28 Javascript
微信小程序之ES6与事项助手的功能实现
2016/11/30 Javascript
jQuery+vue.js实现的多选下拉列表功能示例
2019/01/15 jQuery
Angular 多模块项目构建过程
2020/02/13 Javascript
JS面向对象编程实现的Tab选项卡案例详解
2020/03/03 Javascript
微信小程序中的列表切换功能实例代码详解
2020/06/09 Javascript
Selenium执行JavaScript脚本的方法示例
2020/12/31 Javascript
[01:09]模型精美,特效酷炫!TI9不朽宝藏Ⅰ鉴赏
2019/05/10 DOTA
Python中用pycurl监控http响应时间脚本分享
2015/02/02 Python
Python基础练习之用户登录实现代码分享
2017/11/08 Python
python 删除指定时间间隔之前的文件实例
2018/04/24 Python
python 读取txt中每行数据,并且保存到excel中的实例
2018/04/29 Python
基于python的图片修复程序(实现水印去除)
2018/06/04 Python
Python实现点阵字体读取与转换的方法
2019/01/29 Python
使用django的ORM框架按月统计近一年内的数据方法
2019/07/18 Python
Python实现RabbitMQ6种消息模型的示例代码
2020/03/30 Python
Python包和模块的分发详细介绍
2020/06/19 Python
Python 爬取淘宝商品信息栏目的实现
2021/02/06 Python
简单几步用纯CSS3实现3D翻转效果
2019/01/17 HTML / CSS
Nuts.com:优质散装,批发坚果、干果和巧克力等
2017/03/21 全球购物
String s = new String(“xyz”);创建了几个String Object?
2015/08/05 面试题
Vector, ArrayList, HashTable, HashMap哪些是线程安全的,哪些不是
2015/10/12 面试题
法律专业个人实习自我鉴定
2013/09/23 职场文书
2015年度企业工作总结
2015/05/21 职场文书
宾馆安全管理制度
2015/08/06 职场文书
网络安全倡议书(3篇)
2019/09/18 职场文书
浅析MySQL如何实现事务隔离
2021/06/26 MySQL