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的模态div层弹出效果
Aug 21 Javascript
JavaScript数值数组排序示例分享
May 27 Javascript
js实现仿京东2级菜单效果(带延时功能)
Aug 27 Javascript
js图片跟随鼠标移动代码
Nov 26 Javascript
Jquery zTree 树控件异步加载操作
Feb 25 Javascript
微信小程序 WXML、WXSS 和JS介绍及详解
Oct 08 Javascript
JS之if语句对接事件动作逻辑(详解)
Jun 28 Javascript
vue实现点击图片放大效果
Aug 15 Javascript
iView-admin 动态路由问题的解决方法
Oct 03 Javascript
JavaScript实现好看的跟随彩色气泡效果
Feb 06 Javascript
element中table高度自适应的实现
Oct 21 Javascript
JS中循环遍历数组的四种方式总结
Jan 23 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远程采集图片详细教程
2014/07/01 PHP
php生成图片验证码-附五种验证码
2015/08/19 PHP
Yii实现Command任务处理的方法详解
2016/07/14 PHP
php简单随机字符串生成方法示例
2017/04/19 PHP
php mysql数据库操作类(实例讲解)
2017/08/06 PHP
php 后端实现JWT认证方法示例
2018/09/04 PHP
再论Javascript下字符串连接的性能
2011/03/05 Javascript
了不起的node.js读书笔记之node的学习总结
2014/12/22 Javascript
JS Attribute属性操作详解
2016/05/19 Javascript
jquery  实现轮播图详解及实例代码
2016/10/12 Javascript
vue如何引用其他组件(css和js)
2017/04/13 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(上)
2018/04/18 Javascript
vue 对axios get pust put delete封装的实例代码
2020/01/05 Javascript
Vue表单提交点击事件只允许点击一次的实例
2020/10/23 Javascript
Python字符转换
2008/09/06 Python
Python专用方法与迭代机制实例分析
2014/09/15 Python
以一段代码为实例快速入门Python2.7
2015/03/31 Python
Python正则表达式实现截取成对括号的方法
2017/01/06 Python
python科学计算之numpy——ufunc函数用法
2019/11/25 Python
Python 之 Json序列化嵌套类方式
2020/02/27 Python
Window系统下Python如何安装OpenCV库
2020/03/05 Python
后端开发使用pycharm的技巧(推荐)
2020/03/27 Python
Css3实现无缝滚动防抖
2020/09/14 HTML / CSS
银行实习自我鉴定
2013/10/12 职场文书
护士自荐信怎么写
2013/10/18 职场文书
英语专业应届生求职信范文
2013/11/15 职场文书
同学聚会欢迎辞
2014/01/14 职场文书
优秀部门获奖感言
2014/02/14 职场文书
高中学生期末评语
2014/04/25 职场文书
环境卫生倡议书
2014/08/29 职场文书
付款承诺函范文
2015/01/21 职场文书
经理聘任证明
2015/03/02 职场文书
nginx服务器的下载安装与使用详解
2021/08/02 Servers
Oracle 临时表空间SQL语句的实现
2021/09/25 Oracle
Mysql数据库手动及定时备份步骤
2021/11/07 MySQL
app场景下uniapp的扫码记录
2022/07/23 Java/Android