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 相关文章推荐
Ext javascript建立超链接,进行事件处理的实现方法
Mar 22 Javascript
javascript 类定义的4种方法
Sep 12 Javascript
对于this和$(this)的个人理解
Sep 08 Javascript
javascript制作loading动画效果 loading效果
Jan 14 Javascript
JavaScript动态改变div属性的实现方法
Jul 22 Javascript
jQuery数据类型小结(14个)
Jan 08 Javascript
JavaScript中split与join函数的进阶使用技巧
May 03 Javascript
一步步教会你微信小程序的登录鉴权
Apr 09 Javascript
JavaScript中click和onclick本质区别与用法分析
Jun 07 Javascript
vue如何解决循环引用组件报错的问题
Sep 22 Javascript
js实现圆形显示鼠标单击位置
Feb 11 Javascript
vue.js中使用微信扫一扫解决invalid signature问题(完美解决)
Apr 11 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 组件化编程技巧
2009/06/06 PHP
php实现的获取网站备案信息查询代码(360)
2013/09/23 PHP
destoon文章模块调用企业会员资料的方法
2014/08/22 PHP
PHP中的替代语法简介
2014/08/22 PHP
老生常谈PHP面向对象之标识映射
2017/06/21 PHP
Laravel使用支付宝进行支付的示例代码
2017/08/16 PHP
Smarty缓存机制实例详解【三种缓存方式】
2019/07/20 PHP
区分JS中的undefined,null,&quot;&quot;,0和false
2007/03/08 Javascript
javascript图像处理—仿射变换深度理解
2013/01/16 Javascript
js实现上传图片之上传前预览图片
2013/03/25 Javascript
jquery实现输入框动态增减的实例代码
2013/07/14 Javascript
使用GruntJS构建Web程序之构建篇
2014/06/04 Javascript
微信小程序 开发指南详解
2016/09/27 Javascript
基于JavaScript实现本地图片预览
2017/02/08 Javascript
nodejs搭建本地服务器并访问文件的方法
2017/03/03 NodeJs
详解用webpack把我们的业务模块分开打包的方法
2017/07/20 Javascript
vue 监听某个div垂直滚动条下拉到底部的方法
2018/09/15 Javascript
JavaScript 中 JSON.parse 函数 和 JSON.stringify 函数
2018/12/05 Javascript
Vue中CSS动画原理的实现
2019/02/13 Javascript
python下函数参数的传递(参数带星号的说明)
2010/09/19 Python
python 排列组合之itertools
2013/03/20 Python
5种Python单例模式的实现方式
2016/01/14 Python
Python的Flask框架应用程序实现使用QQ账号登录的方法
2016/06/07 Python
flask入门之文件上传与邮件发送示例
2018/07/18 Python
Python实现的矩阵转置与矩阵相乘运算示例
2019/03/26 Python
Django页面数据的缓存与使用的具体方法
2019/04/23 Python
解决pycharm导入本地py文件时,模块下方出现红色波浪线的问题
2020/06/01 Python
聊聊python中的循环遍历
2020/09/07 Python
CSS3模拟IOS滑动开关效果
2016/09/28 HTML / CSS
CSS3 filter(滤镜)实现网页灰色或者黑色模式的示例代码
2021/02/24 HTML / CSS
定制iPhone和Macbook保护壳:Slick Case
2018/11/21 全球购物
"序列点" 是什么
2016/07/29 面试题
争做文明公民倡议书
2014/08/29 职场文书
财务经理岗位职责范本
2015/04/08 职场文书
2015年大学学生会工作总结
2015/05/13 职场文书
中学生打架《检讨书》范文
2019/08/12 职场文书