博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript闭包简单理解
阅读量:7110 次
发布时间:2019-06-28

本文共 1990 字,大约阅读时间需要 6 分钟。

原文:

提到闭包,想必大家都早有耳闻,下面说下我的简单理解。

说实话平时工作中实际手动写闭包的场景并不多,但是项目中用到的第三方框架和组件或多或少用到了闭包。
所以,了解闭包是非常必要的。呵呵...
一、什么是闭包
简而言之,就是能够读取其他函数内部变量的函数
由于JS变量作用域的特性,外部不能访问内部变量,内部可以外部变量。
二、使用场景
1. 实现私有成员。
2. 保护命名空间,避免污染全局变量。
3. 缓存变量。

先看一个封装的例子:

var person = function () {    // 变量作用域为函数内部,外部无法访问    var name = "default";    return {        getName: function () {            return name;        },        setName: function (newName) {            name = newName;        }    }}();console.log(person.name); // 直接访问,结果为:undefinedconsole.log(person.getName()); // 结果为:defaultconsole.log(person.setName("langjt"));console.log(person.getName()); // 结果为:langjt

再看循环中常用闭包解决引用外部变量问题:

var aLi = document.getElementsByTagName('li');for (var i=0, len=aLi.length; i
元素,弹出的值都为len,表明这里的i和在for之后打印i的值是一样的。 };}

使用闭包后:

var aLi = document.getElementsByTagName('li');for (var i=0, len=aLi.length; i
元素,就会弹出对应的下标了。 } })(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现在是两个新的函数,作用是将传入的参数值 (+/‐)1alert(inc(99));//100alert(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");

 

转载地址:http://fslhl.baihongyu.com/

你可能感兴趣的文章
JavaScript 性能优化技巧分享
查看>>
JavaScript入门详解
查看>>
MySQL分布式集群之MyCAT(三)rule的分析
查看>>
nginx编译安装优化
查看>>
后台(34)——MyBatis概述
查看>>
SpringMVC(转)
查看>>
VSTO之旅系列(三):自定义Excel UI
查看>>
HDOJ(HDU) 1570 A C
查看>>
Excel插入当前日期
查看>>
SharePoint 2013 入门教程之创建页面布局及页面
查看>>
[20171205]uniq命令的输入输出.txt
查看>>
Silk codec的一些资料
查看>>
PHP上传文件大小限制解决方法
查看>>
SQL Server 优化---为什么索引视图(物化视图)需要with(noexpand)强制查询提示
查看>>
Android Studio 添加 Genymotion插件
查看>>
德勤系统受黑客攻击,客户保密邮件泄露
查看>>
Office 365 – SharePoint 2013 Online 之WebPart开发、部署教程
查看>>
Uber前CEO Kalanick首度对Benchmark诉讼发声
查看>>
Makefile 实际用例分析(二) ------- 比较通用的一种架构
查看>>
DJANGO中获取登陆用名及别名
查看>>