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核心支持代码分享
May 23 Javascript
jQuery插件开发的两种方法及$.fn.extend的详解
Jan 16 Javascript
Angularjs的Controller间通信机制实例分析
Nov 07 Javascript
Javascript封装id、class与元素选择器方法示例
Mar 13 Javascript
使用Angular CLI进行Build(构建)和Serve详解
Mar 24 Javascript
对vue2.0中.vue文件页面跳转之.$router.push的用法详解
Aug 24 Javascript
js中的闭包实例展示
Nov 01 Javascript
浅谈express.js框架中间件(middleware)
Apr 07 Javascript
Electron vue的使用教程图文详解
Jul 05 Javascript
JS插入排序简单理解与实现方法分析
Nov 25 Javascript
微信小程序之左右布局的实现代码
Dec 13 Javascript
如何在JavaScript中正确处理变量
Dec 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
2019年漫画销量排行榜:鬼灭登顶 海贼单卷制霸 尾田盛赞鬼灭
2020/03/08 日漫
PHP实现动态柱状图改进版
2015/03/30 PHP
PHP自动生成表单代码分享
2015/06/19 PHP
PHP implode()函数用法讲解
2019/03/08 PHP
js简单的弹出框有关闭按钮
2014/05/05 Javascript
jQuery实现冻结表格行和列
2015/04/29 Javascript
你不知道的高性能JAVASCRIPT
2016/01/18 Javascript
JavaScript中数组的22种方法必学(推荐)
2016/07/20 Javascript
JS绘制微信小程序画布时钟
2016/12/24 Javascript
在vue2.0中引用element-ui组件库的方法
2018/06/21 Javascript
使用xampp将angular项目运行在web服务器的教程
2019/09/16 Javascript
NodeJS有难度的面试题(能答对几个)
2019/10/09 NodeJs
微信小程序登录时如何获取input框中的内容
2019/12/04 Javascript
Vue双向绑定实现原理与方法详解
2020/05/07 Javascript
python中二维阵列的变换实例
2014/10/09 Python
python Django框架实现自定义表单提交
2016/03/25 Python
Python使用pyh生成HTML文档的方法示例
2018/03/10 Python
Python 数据处理库 pandas进阶教程
2018/04/21 Python
Python类的继承、多态及获取对象信息操作详解
2019/02/28 Python
Python3.6+Django2.0以上 xadmin站点的配置和使用教程图解
2019/06/04 Python
Python Web框架之Django框架文件上传功能详解
2019/08/16 Python
使用Python将字符串转换为格式化的日期时间字符串
2019/09/01 Python
使用Python的Turtle绘制哆啦A梦实例
2019/11/21 Python
python requests模拟登陆github的实现方法
2019/12/26 Python
基于CSS3实现的黑色个性导航菜单效果
2015/09/14 HTML / CSS
HTML5 Geolocation API的正确使用方法
2018/12/04 HTML / CSS
使用jTopo给Html5 Canva中绘制的元素添加鼠标事件
2014/05/15 HTML / CSS
荷兰本土平价百货:HEMA
2017/10/23 全球购物
人事科岗位职责范本
2014/03/02 职场文书
机电一体化应届生求职信
2014/08/09 职场文书
销售业务员岗位职责
2015/02/13 职场文书
居委会工作总结2015
2015/05/18 职场文书
2015年庆祝国庆节66周年演讲稿
2015/07/30 职场文书
2016年幼儿园教研活动总结
2016/04/05 职场文书
导游词之丽江普济寺
2019/10/22 职场文书
MySQL数据库安装方法与图形化管理工具介绍
2022/05/30 MySQL