前言

旧的没有搬过来,先写一下新的感悟。

正文

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 闭包(新)的更多相关文章

  1. 大部分人都会做错的经典JS闭包面试题

    由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...

  2. Js闭包的用途

    本来想总结一点JavaScript中的闭包的一些用法,在查资料的时候发现了一篇很好的文章,就转过来收藏了,下面附上传送门: js闭包的用途 ---------sunlylorn 我们来看看闭包的用途. ...

  3. js闭包的作用

    js闭包的用途详解 js闭包可以用在许多地方.它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中.具体怎么理解呢,各位看官请仔细看好下文   我们来看 ...

  4. 探讨js闭包

    背景:爱就要大胆说出来,对于编程我只想说,喜欢就大胆写出来.喜欢却不行动那就意味着失败.所以,对于在研究编程的猿们,我对同伴们说,大胆的学,大胆的写.呵呵,说这些其实无非是给我自己点动力,写下去的勇气 ...

  5. javascript深入理解js闭包(转)

    javascript深入理解js闭包 转载  2010-07-03   作者:    我要评论 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...

  6. js闭包的用途详解

    js闭包可以用在许多地方.它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中 我们来看看闭包的用途.事实上,通过使用闭包,我们可以做很多事情.比如模拟 ...

  7. 简单详细讲解js闭包(看完不懂你砍我!!!)

    <javascript高级程序设计>中闭包的概念: 闭包,其实是一种语言特性,它是指的是程序设计语言中,允许将函数看作对象,然后能像在对象中的操作般在函数中定义实例(局部)变量,而这些变量 ...

  8. 【闭包】JS闭包深入理解

    先看题目代码: 1 2 3 4 5 6 7 8 9 10 11 12 function fun(n,o) {  console.log(o)  return {   fun:function(m){ ...

  9. JS闭包的理解及常见应用场景

    JS闭包的理解及常见应用场景 一.总结 一句话总结: 闭包是指有权访问另一个函数作用域中的变量的函数 1.如何从外部读取函数内部的变量,为什么? 闭包:f2可以读取f1中的变量,只要把f2作为返回值, ...

  10. js闭包的作用域以及闭包案列的介绍:

    转载▼ 标签: it   js闭包的作用域以及闭包案列的介绍:   首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几 ...

随机推荐

  1. RocketMQ(3) 根据消息key查询功能的实现: indexFile

    三: indexFile 除了通过通常的指定Topic进行消息消费外,RocketMQ还提供了根据key进行消息查询的功能. 该查询是通过store目录中的index子目录中的indexFile进行索 ...

  2. Java interface 接口的使用 implements 实现----

    1 package com.bytezreo.interfacetest; 2 3 /** 4 * 5 * @Description interface 接口的使用 implements 实现---- ...

  3. day34-IO流01

    IO流01 1.文件基础知识 什么是文件? 文件,我们并不陌生.文件是保存数据的地方.比如大家经常使用的word文档,txt文件,excel文件等,都是文件.它既可以保存一张图片,也可以保存声音.视频 ...

  4. Java8的核心功能就是Lambda和Streaming API

    Java8的核心功能就是Lambda和Streaming API

  5. 引领AI创意教育新浪潮,瑞云AIGC实训平台解决方案来了

    过去的2023年,AI(人工智能)成为了年度科技圈关键词,各行各业都在AI化,据统计,AIGC市场规模预计到2030年将达到万亿级别,这不仅是市场的趋势,更是创新的机遇. 教育行业更是如此,许多高校和 ...

  6. 工作记录:Vue3.0新特性

    简单对比 Vue2.x 与 Vue3.x 响应式 Vue2 使用Object.defineProperty劫持对象的属性 Vue3 使用Proxy 直接代理对象 由于Object.defineProp ...

  7. LOTO示波器客户应用案例展示

    LOTO示波器客户应用案例展示 LOTO示波器以软件功能为核心,采用独特的积木式可扩展的硬件架构,为多行业的电子电路研发工程师提供高性价比的解决方案.我们初步汇总了一些客户实测的应用案例展示如下: 1 ...

  8. nuxt环境目录结构

  9. springboot整合视频点播

    1 //上传视频到阿里云 2 @Override 3 public String uploadAyl(MultipartFile file) { 4 try { 5 //accessKeyId,acc ...

  10. KingbaseESV8R6 heap table末端垃圾页回收机制

    前言 默认情况下,vacuum表不能释放磁盘空间,只是在dead tuple做个标记位,但heap table末端的垃圾页可以被truncate,从磁盘中释放空间.例如表的末尾的100个数据块里面全是 ...