js 闭包(新)
前言
旧的没有搬过来,先写一下新的感悟。
正文
ECMAScript中,闭包指的是:
从理论角度:所有的函数。因为它们都在创建的时候就将上层上下文的数据保存起来了。哪怕是简单的全局变量也是如此,因为函数中访问全局变量就相当于是在访问自由变量,这个时候使用最外层的作用域。
从实践角度:以下函数才算是闭包:
1.即使创建它的上下文已经销毁,它仍然存在(比如,内部函数从父函数中返回)
2.在代码中引用了自由变量
什么是自由变量:
自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。
那么我们现在只考虑实践角度,第二点很好满足,第一点有一丢丢难呢。
先看下闭包:
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
var foo = checkscope();
foo();
按照我的上一篇js的上下文。
理论上scope 是访问不到var scope = "local scope";的。
我在这里简单的分析一下,详细可以去看我的。
首先得到全局上下文,进入栈中。
然后checkscope 上下文进入栈。
当执行完毕,checkscope 上下文出栈了。
问题就在这里,既然上下文出栈了,那么应该f这个函数执行的时候,就应该访问不到checkscope 的上下文了,垃圾就会回收checkscope 的上下文。
这个问题就出现了。
但是你没有有听说过闭包造成内存问题?
问题就出再f创建的时候,会扫码他所在环境的上下文,如果引用了上下文的作用链对象,那么会保留上下文。
function a()
{
var x=1;
var c= function b()
{
return function (){
return x;
}
}
return function()
{
return c;
}
}
console.log(a()()()());
只要是作用链上的都会保留到,返回结果为1。
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = function () {
console.log(i);
};
}
data[0]();
data[1]();
data[2]();
为何其会返回都是3?
按照上下文理解,那么是:
在执行匿名函数的时候,上下文栈中只剩下全局上下文,访问的就只有去全局的。
那么可以这样写:
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = (function (i) {
return function(){
console.log(i);
}
})(i);
}
data[0]();
data[1]();
data[2]();
关键部分在这个i:
(function (i) {
return function(){
console.log(i);
}
})(i);
这样i,相当于这样的。
(function (i) {
var i=i;
return function(){
console.log(i);
}
})(i);
这就是说这个i和循环中的i没有半毛钱关系,因为其不是引用对象。
下面我写了一个引用对象的:
var data=[];
var args={i:0};
for (var i = 0; i < 3; i++) {
args.i=i;
data[i] = (function (args) {
return function () {
console.log(args.i);
}
})(args);
}
data[0]();
data[1]();
data[2]();
这样的闭包不仅没有效果,而且还出内存问题。
js 闭包(新)的更多相关文章
- 大部分人都会做错的经典JS闭包面试题
由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...
- Js闭包的用途
本来想总结一点JavaScript中的闭包的一些用法,在查资料的时候发现了一篇很好的文章,就转过来收藏了,下面附上传送门: js闭包的用途 ---------sunlylorn 我们来看看闭包的用途. ...
- js闭包的作用
js闭包的用途详解 js闭包可以用在许多地方.它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中.具体怎么理解呢,各位看官请仔细看好下文 我们来看 ...
- 探讨js闭包
背景:爱就要大胆说出来,对于编程我只想说,喜欢就大胆写出来.喜欢却不行动那就意味着失败.所以,对于在研究编程的猿们,我对同伴们说,大胆的学,大胆的写.呵呵,说这些其实无非是给我自己点动力,写下去的勇气 ...
- javascript深入理解js闭包(转)
javascript深入理解js闭包 转载 2010-07-03 作者: 我要评论 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
- js闭包的用途详解
js闭包可以用在许多地方.它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中 我们来看看闭包的用途.事实上,通过使用闭包,我们可以做很多事情.比如模拟 ...
- 简单详细讲解js闭包(看完不懂你砍我!!!)
<javascript高级程序设计>中闭包的概念: 闭包,其实是一种语言特性,它是指的是程序设计语言中,允许将函数看作对象,然后能像在对象中的操作般在函数中定义实例(局部)变量,而这些变量 ...
- 【闭包】JS闭包深入理解
先看题目代码: 1 2 3 4 5 6 7 8 9 10 11 12 function fun(n,o) { console.log(o) return { fun:function(m){ ...
- JS闭包的理解及常见应用场景
JS闭包的理解及常见应用场景 一.总结 一句话总结: 闭包是指有权访问另一个函数作用域中的变量的函数 1.如何从外部读取函数内部的变量,为什么? 闭包:f2可以读取f1中的变量,只要把f2作为返回值, ...
- js闭包的作用域以及闭包案列的介绍:
转载▼ 标签: it js闭包的作用域以及闭包案列的介绍: 首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几 ...
随机推荐
- USB数据传输与手机授权:充电宝常规使用不需要授权
概述 此篇为解答充电宝骗局问题,骗局概述:两个人做局,以充测试充电宝是否损坏为由,插到受骗者手机上,受骗者允许了手机弹出的授权请求后,偷偷将病毒注入手机. Q:什么情况下手机会弹出授权? A:手机用数 ...
- 删除文件或目录 被进程占用或锁定locked 查询进程 资源监视器-cpu-关联句柄-输入文件全路径
删除文件或目录 被进程占用或锁定 查询进程 资源监视器-cpu-关联句柄-输入文件全路径 右键点击桌面的Win图标,点击"任务管理器">>点击左上角"性能&q ...
- Spring 中不得不了解的姿势
说明 本文非原创,我只是进行了整理以及做了一些改动,仅供学习,若需进行商业使用,请联系原作者 原作者:苏三 原文链接:苏三说技术:Spring系列 Spring IOC 本章节解读的流程为Spring ...
- 地理探测器R语言实现:geodetector
本文介绍基于R语言中的geodetector包,依据多张栅格图像数据,实现地理探测器(Geodetector)操作的详细方法. 需要说明的是,在R语言中进行地理探测器操作,可以分别通过geod ...
- 07.Java类加载问题
目录介绍 7.0.0.1 Java内存模型里包含什么?程序计数器的作用是什么?常量池的作用是什么? 7.0.0.2 什么是类加载器?类加载器工作机制是什么?类加载器种类?什么是双亲委派机制? 7.0. ...
- 记录--JS 的垃圾回收机制
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 垃圾回收(Garbage Collection)是一种内存管理机制,用于检测和清理不再被程序使用的内存,这些不再被使用的内存就被称为 ...
- 大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧及AI未来展望—打造AI应用新篇章
大模型落地实战指南:从选择到训练,深度解析显卡选型.模型训练技.模型选择巧及AI未来展望---打造AI应用新篇章 0.前言大模型发展史 早期阶段(1950s~1980s) 在1950年代初期,人们开始 ...
- react-naive工作原理
react-naive工作原理是从react的工作原理衍生出来的 react的工作原理 在react中,virtual dom 就像一个中间层,介于开发者描述的视图与实际在页面上渲染的视图之间.为了在 ...
- 【IOT安全】ASA5520基本知识和配置
本文主要介绍ASA5520防火墙的基本知识和配置 环境搭建 Linux eveng 5.17.8-eve-ng-uksm-wg+ #1 SMP PREEMPT Mon May 16 10:08:59 ...
- Nancy如何接收POST过来的Json数据
当Nancy版本为2.0.0.0时 string postData = Request.Body.AsString; 当Nancy版本为1.4.5.0时 自己写一个扩展方法,代码如下 /// < ...