探究JavaScript闭包
什么是JavaScript闭包?
刚开始知道这个词,就误以为是自动执行的匿名函数块。
比如说+function(){}();
然而并不是,那么请看下面的例子:
function init() {
var name = "initial";
function displayName() {//displayName() is the inner function, a closure
alert(name);
}
displayName();
}
init();
displayname()是闭包吗?函数内部访问函数成员局部属性的方法?
This is an example of lexical scoping: in JavaScript, the scope of a variable is defined by its location within the source code (it is apparent lexically) and nested functions have access to variables declared in their outer scope
这是一个词法域的例子:Javascript中,变量的作用域由他所在的代码区域(明显的词法上的),和可以访问外部作用域的嵌套方法组成。
闭包Closure
再看这个例子:
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
What’s different — and interesting — is that the displayName() inner function was returned from the outer function before being executed.
不同并且有趣的地方是:内部方法displayName在函数外面被return出来,还是在执行之前。
那么可以大胆的说:myFunc就是一个闭包。
A closure is a special kind of object that combines two things: a function, and the environment in which that function was created.
闭包就是一个包含了两个东西的特殊对象:一个方法和创建这个方法的环境。
再看看一个例子 :
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
显然add5和add10各自都有各自的环境,所持有的变量是不同的。
看一个闭包引起的错误,比较难理解透。
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
}
}
setupHelp();
如果有三个输入框,那么每个框点击都会导致#help的内容变成Your age (you must be over 16)。
原因是:赋值给document.getElementById(item.id).onfocus
的function是个闭包函数:,这里循环创建了三个闭包,但是他们共享了同一个外部作用域,也就是setupHelp,那么自然循环结束的时候,onfocus 里面就是指向了数据的最后一个元素。
这些话并不太容易让人相信。
我debug跟踪了一下:
循环走完的时候,onfocus function(){}里面 item 的id已经是’age’,help是
‘Your age (you must be over 16)’
三个input对象都是onfocus绑定了同一个闭包(等同于同一个,环境里变量和函数行为都一样)。
闭包性能
通常一个函数执行完毕之后它内部的局部变量就已经不能再访问了。
而闭包需要维持他所被创建时的作用域环境,过分使用闭包对速度上的性能和内部的消耗是有影响的。没必要的时候不要使用闭包。
本文引用自:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
探究JavaScript闭包的更多相关文章
- JavaScript闭包深入解析
for (var i=1; i<=5; i++) { setTimeout( function timer() { console.log( i ); }, i*1000 ); } --上面这段 ...
- Javascript闭包的一些研究
原文:Javascript闭包的一些研究 本文不谈闭包的概念,因为概念容易把人搞晕,本文希望通过几个鲜活的例子来探究闭包的性质,相信对理解闭包会有所帮助. 程序1 var f = (function( ...
- 《Web 前端面试指南》1、JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- JavaScript闭包(Closure)
JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...
- Javascript闭包和C#匿名函数对比分析
C#中引入匿名函数,多少都是受到Javascript的闭包语法和面向函数编程语言的影响.人们发现,在表达式中直接编写函数代码是一种普遍存在的需求,这种语法将比那种必须在某个特定地方定义函数的方式灵活和 ...
- javascript闭包理解
//闭包理解一 function superFun(){ var _super_a='a'; function subfuc(){ console.log(_super_a); } return su ...
- Javascript闭包深入解析及实现方法
1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点:1. 作为一个函数变量的一个引用,当函数返回时 ...
- javascript闭包和作用域链
最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...
随机推荐
- SpringMVC 图片上传虚拟目录
可以直接在tomcat的server.xml文件中进行设置,位置在Host中 添加内容为:<Context docBase="G:\JAVAtest\temp" path=& ...
- commons-beanutils.jar及其支持文件
下载地址: 链接:https://pan.baidu.com/s/1AtiK3nsk0aBuBfMdNwBVGw 密码:6tul
- MapReduce之Job提交流程源码和切片源码分析
hadoop2.7.2 MapReduce Job提交源码及切片源码分析 首先从waitForCompletion函数进入 boolean result = job.waitForCompletion ...
- 23种设计模式之装饰器模式(Decorator Pattern)
装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...
- .NetCore技术研究-.NET Core迁移前的准备工作
前段时间迁移.NET Core做了大量的试水和评估,今天整理一下分享给大家.大致有以下几个部分: 1. .NET Core的由来 2. 为什么要迁移.NET Core 3. .NET Core3.X主 ...
- 常用Form表单正则表达式
前端常用form表单提交,校验正则表达式奉上!/** * 邮箱 * @param {*} s */ export function isEmail (s) { return /^([a-zA-Z0-9 ...
- 【柠檬班】史上最简单的Jmeter跨线程组取参数值的两种办法(不写代码)【原创】
如果你工作中已经在用jmeter做接口测试,或性能测试了,你可能会遇到一个麻烦,哪就是jmeter的变量值不能跨线程组传递. 看,官方就已经给出了解释.这个不是jmeter的缺陷,这是jmeter ...
- JVM(三)初始化
字节码指令和符号引用.直接引用 1.主动引用和被动引用 主动引用:虚拟机规定只有满足四个情况的的情况下,才会进行主动引用. 被动引用:除过四种情况的引用是被动引用. 只有主动引用才会初始 ...
- Java的一些基础知识深入
1.浅析Java中的final关键字: 2.Java中的static关键字解析: 3.探秘Java中String.StringBuilder以及StringBuffer: 4.Java内部类详解: 5 ...
- axios对put操作对Android的支持之坑
### 前段时间我做的一个手机端H5项目,需要发送一个put请求.因为ajax现在用的人有点少了,而且公司里边都是用的axios,所以我也是用的是axios做的请求. ### 再开发的时候测试都没有问 ...