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 相关文章推荐
javascript中的107个基础知识收集整理 推荐
Mar 29 Javascript
JS预览图像将本地图片显示到浏览器上
Aug 25 Javascript
JavaScript关闭当前页面(窗口)不带任何提示
Mar 26 Javascript
jQuery插件pagewalkthrough实现引导页效果
Jul 05 Javascript
js生成随机颜色方法代码分享(三种)
Dec 29 Javascript
vuex中的 mapState,mapGetters,mapActions,mapMutations 的使用
Apr 13 Javascript
详解Node.js中path模块的resolve()和join()方法的区别
Oct 29 Javascript
laydate如何根据开始时间或者结束时间限制范围
Nov 15 Javascript
Vue.js标签页组件使用方法详解
Oct 19 Javascript
vue项目实现多语言切换的思路
Sep 17 Javascript
详解JavaScript原型与原型链
Nov 16 Javascript
javascript代码实现简易计算器
Jan 25 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
世界咖啡生产者论坛呼吁:需要立即就咖啡价格采取认真行动
2021/03/06 咖啡文化
php写的简易聊天室代码
2011/06/04 PHP
php+xml结合Ajax实现点赞功能完整实例
2015/01/30 PHP
详谈symfony window下的安装 安装时候出现的问题以及解决方法
2017/09/28 PHP
prototype.js的Ajax对象
2006/09/23 Javascript
使用jQuery快速解决input中placeholder值在ie中无法支持的问题
2014/01/02 Javascript
jQuery的3种请求方式$.post,$.get,$.getJSON
2014/03/28 Javascript
jquery中checkbox使用方法简单实例演示
2015/11/24 Javascript
JS与jQ读取xml文件的方法
2015/12/08 Javascript
基于bootstrap实现多个下拉框同时搜索功能
2017/07/19 Javascript
详解Webpack实战之构建 Electron 应用
2017/12/25 Javascript
vue2.0模拟锚点的实例
2018/03/14 Javascript
使用Angular CLI进行Build(构建)和Serve详解
2018/03/24 Javascript
Nodejs实现多文件夹文件同步
2018/10/17 NodeJs
jQuery实现侧边栏隐藏与显示的方法详解
2018/12/22 jQuery
jquery实现选项卡切换代码实例
2019/05/14 jQuery
Vue 实现前进刷新后退不刷新的效果
2019/06/14 Javascript
Vue 使用计时器实现跑马灯效果的实例代码
2019/07/11 Javascript
[04:30]显微镜下的DOTA2第五期——拉比克
2013/09/26 DOTA
[01:07:19]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第一场 1月19日
2021/03/11 DOTA
解决python xlrd无法读取excel文件的问题
2018/12/25 Python
python2和python3实现在图片上加汉字的方法
2019/08/22 Python
python Opencv计算图像相似度过程解析
2019/12/03 Python
Django关于admin的使用技巧和知识点
2020/02/10 Python
PyTorch 导数应用的使用教程
2020/08/31 Python
详解Anaconda 的安装教程
2020/09/23 Python
html5 touch事件实现页面上下滑动效果【附代码】
2016/03/10 HTML / CSS
德国黑胶唱片、街头服装及运动鞋网上商店:HHV
2018/08/24 全球购物
英国高街奥特莱斯:Highstreet Outlet
2019/11/21 全球购物
《学会合作》教学反思
2014/04/12 职场文书
小学班级口号
2014/06/09 职场文书
会计人员演讲稿
2014/09/11 职场文书
2015年人事工作总结范文
2015/04/09 职场文书
2016年“12.4”法制宣传日活动总结
2016/04/01 职场文书
Python 机器学习工具包SKlearn的安装与使用
2021/05/14 Python
常用的文件对应的MIME类型汇总
2022/04/26 HTML / CSS