精华内容
下载资源
问答
  • 总共遇到了两个有关闭包的问题。  1.以下代码的运行结果是什么,如果希望看到控制台每隔一秒... 由于在setTimeout函数里面的匿名函数内引用了外部的变量i,造成了闭包问题。控制台会连续打印9个是10.所以解决该问题

       总共遇到了两个有关闭包的问题。

      1.以下代码的运行结果是什么,如果希望看到控制台每隔一秒连续输出1-9,应该如何修改代码

    for(var i=1;i<10;i++){

    setTimeout(function(){

    console.log(i);

    },1000);

    }

        由于在setTimeout函数里面的匿名函数内引用了外部的变量i,造成了闭包问题。控制台会连续打印9个是10.所以解决该问题的要点就是解决闭包问题。解决闭包的方法,可以采用匿名函数。模仿块级作用域的方法。

      我自己写的方法如下(当时小手一抖,我就把num*1000写成了1000大哭):

    for (var i = 1; i < 10; i++) {
    (function(num){
    setTimeout(function(){
    console.log(num);
    },num*1000);
    })(i);

    }

    2

    function addEventOnclick(){
    var as=document.getElementsByTagName('a');
    for(key in as){
    var text=as[key].innerHTML;
    as[key].οnclick=(function(t){//使用匿名函数解决闭包问题
    return function(){
    alert(t);
    };
    })(text);
    }
    }
    addEventOnclick();

    展开全文
  • 闭包解决了什么问题 由于变量的作用域的原因-----(函数内部能读取全局变量,函数外部无法读取函数内部的变量【局部变量】),为了在函数外部读取局部变量,所以就有了闭包闭包的作用 1.访问其他函数内部变量 2....

    什么是闭包?

    能够访问其他函数内部变量的函数

    闭包解决了什么问题
    由于变量的作用域的原因-----(函数内部能读取全局变量,函数外部无法读取函数内部的变量【局部变量】),为了在函数外部读取局部变量,所以就有了闭包。

    闭包的作用
    1.访问其他函数内部变量
    2.保护变量不被内存回收机制回收
    3.避免全局变量被污染 方便调用上下文的局部变量 加强封装性

    闭包的缺点
    闭包长期占用内存,内存消耗很大,可能导致内存泄露

    ## 闭包示例代码如下:
    在这里插入图片描述
    补充:注意事项,如若操作不当,可能会导致内存泄漏。

    什么是内存泄漏
    首先,需要了解浏览器自身的内存回收机制。
    每个浏览器会有自己的一套回收机制,当分配出去的内存不使用的时候便会回收;内存泄露的根本原因就是你的代码中分配了一些‘顽固的’内存,浏览器无法进行回收,如果这些’顽固的’内存还在一直不停地分配就会导致后面所用内存不足,造成泄露。

    闭包造成内存泄漏
    因为闭包就是能够访问外部函数变量的一个函数,而函数是必须保存在内存中的对象,所以位于函数执行上下文中的所有变量也需要保存在内存中,这样就不会被回收,如果一旦循环引用或创建闭包,就会占据大量内存,可能会引起内存泄漏)

    如何避免闭包引起的内存泄漏
    1,在退出函数之前,将不使用的局部变量全部删除。可以使变量赋值为null;(示例如下)
    在这里插入图片描述
    2,避免变量的循环赋值和引用。 (示例如上)

    3,利用Jquery释放自身指定的所有事件处理程序。
    由于jQuery考虑到了内存泄漏的潜在危害,所以*它会手动释放自己指定的所有事件处理程序 *。只要坚持使用jQuery的事件绑定方法,就可以一定程度上避免这种特定的常见原因导致的内存泄漏。
    在这里插入图片描述
    当指定单击事件处理程序时,就创建了一个在其封闭的环境中包含button变量的闭包。而且,现在的button也包含一个指向闭包(onclick属性自身)的引用。这样,就导致了在IE中即使离开当前页面也不会释放这个循环。
    在这里插入图片描述
    闭包应用场景:

    <button id="blue">blue</button>
    <button id="red">red</button>
    <button id="green">green</button>
    
    <script type="text/javascript">
    function changeSize(color){
    		return function(){
    			document.body.style.background = color
    		}
    	}
    	
    	var blue = changeSize('blue')
    	var red = changeSize('red')
    	var green = changeSize('green')
    	
    	document.getElementById('blue').onclick = blue
    	document.getElementById('red').onclick = red
    	document.getElementById('green').onclick = green
    	
    </script>
    

    其实仅避开闭包使用而言,实现的方式有多种

    <button id="blue" data-id="blue">blue</button>
    <button id="red" data-id="red">red</button>
    <button id="green" data-id="green">green</button>
    
    <script src="../libs/jquery/jquery-3.4.1.min.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
    	$("button").click(function(e){
    		let currentButton = $(e.target).data("id");
    		
    		if(currentButton == "blue"){
    			$("body").css({"background":"blue"})
    		}else if(currentButton == "red"){
    			$("body").css({"background":"red"})
    		}else{
    			$("body").css({"background":"green"})
    		}
    	})
    	</script>
    
    展开全文
  • 【重点突破】——如何快速识别并解决闭包问题”? 一、引言 什么是“闭包”?它既是前端程序中常常会碰到的一个千年大坑,也是这个大坑唯一可以解决自身的办法。很多大牛对闭包都有自己的解释...

    【重点突破】——如何快速识别并解决“闭包问题”?

    一、引言

    什么是“闭包”?它既是前端程序中常常会碰到的一个千年大坑,也是这个大坑唯一可以解决自身的办法。很多大牛对闭包都有自己的解释,但每个人的解释可能都不太一样,看太多反而混乱,这里,我会用一个小例子,尽量简单的说明这个“闭包”到底是什么,怎么识别?如何解决?

     

    二、闭包

    • 什么是? 一种对象,向外公开了特定的数据,以及操作这种数据的方法,供外部调用,就是闭包
    • 为什么?  
    1. 全局变量:随处可见,可反复使用。缺点:极易被污染(易被篡改)。
    2. 局部变量:不会被污染。缺点:仅函数内可用,且不可重用(不易被篡改)。
    • 三大特点
    1. 外层函数
    2. 受保护的变量
    3. 内层函数

     

    三、如何形成闭包

          外层函数的作用域对象无法释放,导致:外层函数的局部变量被保存下来(可以重用)。

    • 第一步:将受保护的变量和操作变量的函数封装在一个外层函数;
    • 第二步:外层函数,要将内层函数队形返回;
    • 第三步:使用者调用外层函数,获得内层函数对象。

     

    四、快速识别

    • 向外抛出对象,一定是闭包。
    • 模型:循环函数嵌套一个内层函数对象返回变量值,外部调用此函数对象,得不到不同变量值的,一定是闭包问题。(依据闭包问题的原因,最后得到的值一定都是内层循环函数获得的最后一个变量值) 。

     

    五、例题说明

    点击1,2,3按钮,获得对应按钮值,有如下代码:

     

    <body>
        <h3>JS中的闭包陷阱</h3>
        <button>1</button>
        <button>2</button>
        <button>3</button>
        <script>
           var list = document.querySelectorAll('button');
           for(var i=0;i<list.length;i++){
               var b = list[i];
               b.onclick = function(){
                   console.log(i);
               }
           };
        </script>
     </body>

     

    打印结果:

     

     

    坑:这属于典型的闭包问题,打不出0,1来,全部为3。

    原因:变量i就1个,并且这段代码不仅是对外公开了一个变量i,还公开了三个不同的监听函数,分别绑定给不同的按钮。

     

    如果看所有JS调用完成(函数外打印),i的值,如下:

     

    console.log('JS调用完成,i='+i);

     

    结果:

     

     

    所以:此时所有JS都已调用完成,i的值等于3。但是,按钮的事件监听并没有调用,可它们都要用i,因此,这个时候,再手动调用事件监听,所获得的i值只能是3。

     

    六、解决方法

    闭包问题必须要靠闭包方案来解决

    1. 把原本的一个闭包,拆分成三个闭包(复杂)
    2. 匿名函数,转化为有名函数(简单)

     

    //方法一:把原本的一个闭包拆为三个
    for(var i=0;i<list.length;i++){
        var b = list[i];
        b.onclick = outer(i);
    }
    
    function outer(num){
        function inner(){
           console.log(num);
        }
        return inner;
    }

     

     //方法二:匿名函数变成有名函数
    for(var i=0;i<list.length;i++){
         var b = list[i];
         b.onclick = (function(num){//外部函数--此处传递形参num,注意不能再取i为变量名,否则又会重复
            return function(){//内部函数
            console.log(num);
                }
         })(i);//闭包上下文变量i,实参
    }

    结果:

     

    如果打印btn,实现代码和效果如下:

     

    for(var i=0;i<list.length;i++){
         var b = list[i];
         b.onclick = (function(btn){//外部函数-
            return function(){//内部函数
            console.log(btn);
                }
         })(b);//传递b为实参
    }

     

     


     注:转载请注明出处

    posted @ 2017-10-14 21:44 柳洁琼Elena 阅读(...) 评论(...) 编辑 收藏
    展开全文
  • 这篇文章主要介绍了关于如何解决vue中methods中的方法闭包缓存的问题,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下vue中methods中的方法闭包缓存问题问题背景需求描述在路由的导航栏中需要, 判断...

    这篇文章主要介绍了关于如何解决vue中methods中的方法闭包缓存的问题,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

    vue中methods中的方法闭包缓存问题

    问题背景

    需求描述在路由的导航栏中需要, 判断是否为第一次点击

    需要一个标志位来记录是否点击过

    现状:这个标志位只在一个函数中用过.不希望存放全局

    希望在这个methods中形成闭包, 用来缓存这个函数

    做出如下尝试后, 发现可以实现.

    当前问题:不能在闭包调用时找到正确的this.

    诡异点测试使用时: 返回的this找到了window// 测试使用:

    测试按钮

    var app = new Vue({

    el: '#app',

    methods: {

    test: (() => {

    `use strict`

    console.log(this) // Window

    var flag = true

    return () => {

    console.log(this) // Window

    flag = false

    }

    })()

    }

    })

    实际项目中的this变成了undefined

    更加诡异的是debugger之后, 我们一步步来看

    当前代码:pointJump: (() => {

    let isFirstChanged = false;

    console.log(this);

    debugger;

    return entry => {

    console.log(this);

    console.log(isFirstChanged);

    debugger;

    isFirstChanged = true;

    };

    })(),操作:刷新页面, 第一次函数立即执行

    页面生成完成后: 我们再次通过按钮触发事件: 此时debugger显示内存中为Vue的顶级对象, 而在控制台打印出来的依旧是undefined

    执行过程分析第一次执行的时候为undefined是正常的, 因为第一次闭包执行, 没有找到this

    当我们再次执行的时候, 虽然调用起来的上下文, 也就是this已经改了, 但是因为在作用域中那个this所代表的空间还是undefined, 所以没有能改变过来.

    就造成了我们所看到的诡异的现象.

    与测试文件有差别的原因因为在测试环境下, 没有能开启严格模式.

    经过两次不同位置的的开启尝试, 都不对

    依旧可以找到window对象

    现在推测是在vue内部进行的实现, 因为引入的vue版本不同.需要再进行测试, 看来源码还是要好好过一遍

    var app = new Vue({

    el: '#app',

    methods: {

    test: (() => {

    `use strict`

    console.log(this) // Window

    var flag = true

    return () => {

    console.log(this) // Window

    flag = false

    }

    })()

    }

    })

    最后找到原因的测试因为箭头函数的this是不会改变, 拥有根据父级能够返回的this

    然后因为上面的闭包环境中的this, 指向的一直都是undefinedconst test = (() => {

    let aaa = true;

    return function () {

    console.log(this);

    aaa = false;

    };

    })();

    mainJump(entry) {

    test.call(this);

    },

    解决方法形成闭包返回的函数中, 不要使用箭头函数, 使用function定义即可pointJump: (() => {

    let isFirstChanged = false;

    return function () {

    console.log(this); // Vue的顶级对象

    isFirstChanged = true;

    };

    })(),

    总结箭头函数不会被call, bind等方法改变this指向

    在闭包中返回函数, 缓存变量时, 使用function进行返回函数的定义.

    展开全文
  • 上述代码执行后毫无疑问是10,es6之前解决闭包问题的办法通常是这样的: var ary=[]; for(var i=0;i;i++){ (function(j){ //隐式执行var j=i; ary[j]=function(){ ...
  • 0 1 2 3 4 5 6 [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]上段代码本意是在每个div上都加一个事件,... 如何解决呢。 可以利用匿名函数来加以解决。匿名函数会制动执行,我们可以利用这一特性,来产生一个作用
  • 闭包解决了什么问题 由于变量的作用域的原因-----(函数内部能读取全局变量,函数外部无法读取函数内部的变量【局部变量】),为了在函数外部读取局部变量,所以就有了闭包闭包的作用 1.访问其他函数内部变量 2....
  • 经典闭包问题

    2015-04-18 23:31:00
    这是一个经典的闭包问题,以前自己在项目中也曾遇到过,解决之后就不了了之。今天遇到一个人也遇到了同样的问题,看着很熟悉,于是想回答看看,但是确不知道该如何比较准确的来描述这个问题,我想是因为自己对这个...
  • 关于闭包问题

    2017-06-09 09:25:00
    我在整理闭包问题的时候,看到一道前端面试题for (var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); }, 0); }了解 js 的异步机制的都知道,输出结果是:10 10 10 ... 10然后面试官又问...
  • 1.我们先看一下闭包引起的问题 function test() { var arr = [] for(var i = 0; i < 10; i++){ arr[i] = function () { console.log(i + " ") } } return arr } var arr = test() for(var i = 0; i < 10; i++)...
  • jquery .on()或.click()方法中的参数data如何使用,具体用武之地在哪,能否解决闭包带来的问题
  • Python闭包问题的探讨

    2019-08-01 03:51:59
    今日在更新程序的时候遇到了个问题如何生成多语言的菜单,创建并绑定相应的回调函数? 生成菜单自然是很简单的,一个for循环就好了,但是生成相应函数就??? 正文 在解决以下事件的过程中,又思考得出了...
  • 闭包

    2020-10-27 23:10:03
    如何形成闭包 满足以下2个条件:才形成闭包 1.内部要在此嵌套一个函数,嵌套的函数引用外部的变量 2.嵌套的函数内部可以引用函数外部的参数和变量 为什么要使用闭包 1.解决了外部无法使用内部变量 2.解决了全局变量...
  • 闭包是什么、用处如何   【js-04】闭包是什么?用处如何?   小课堂【上海】   分享人:杨亚洲 目录 1.背景介绍 2.知识剖析 3.常见问题 4.解决方案 5.编码实战 6.扩展思考 7.参考文献 8.更多讨论 ...
  • 用处如何?it修真院小课堂目录1.背景介绍2.知识剖析3.常见问题4.解决方案5.编码实战6.扩展思考7.参考文献8.更多讨论1.背景介绍闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包...
  • js-闭包

    2019-10-26 15:27:53
    函数作为参数for循环和闭包的关系如何解决闭包的实际使用1.闭包封装变量,收敛权限2.闭包解决递归调用闭包的坑1.引用的变量可能会发生变化2.this指向问题3.内存泄露问题 闭包 闭包指的是:能够访问另一个函数作用...
  • 【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】 八个方面深度解析前端知识/技能,本篇分享的是: 【闭包是什么,如何使用?】 1.背景介绍 是Javascript语言的...
  • javaScript-闭包

    2021-02-10 08:35:43
    要理解什么是闭包,首先得知道什么是作用域,作用域分为全局作用域和局部作用域,而计算机语言的奇妙之处就在于局部作用域中可以访问全局变量,而全局作用域不能访问局部变量,如何解决这一问题?这就用到了闭包。 ...
  • Javascript-js闭包详解

    2020-02-18 22:46:03
    本片博客旨在从js的底层逻辑上解释什么是js闭包、js闭包的应用、以及如何解决js闭包的带来的问题
  • 真正了解Javascript闭包

    2020-04-20 05:48:05
    这篇文章将以简单的方式说明Javascript闭包的工作方式。 我们将讨论以下主题和常见问题: ... 理解闭包的最简单方法是了解它们试图解决问题。 让我们以一个简单的代码示例为例,其中一个计数器在循环内递增3次...
  • 深入理解闭包

    2021-02-22 15:58:23
    解决循环输出问题(1)利用 IIFE(2)使用 ES6 中的 let(3)定时器传入第三个参数 1. 作用域 闭包和作用域这两个概念密切相关,所以在说闭包之前,先来看一下作用域的概念。 每一种编程语言,它最基本的能力都是...
  • 大家都知道在ES6之前,JavaScript是没有块级作用域的,但其实我们是可以通过匿名函数的闭包来模仿实现一个块级作用域,并且可以依靠这样的操作来解决平时开发中的两大难题。 公众号:前端印象 不定时有送书活动,...
  • 闭包的基础总结!

    2018-10-30 15:56:30
    Javascript中的闭包问题。 1、什么是闭包:闭包就是能够读取其他函数内部变量的函数。 2、闭包作用:可以访问函数内部的私有变量 、让变量始终存在于内存中而不被释放 3、闭包造成的问题:由于闭包的变量始终存在...
  • 闭包就是能够读取其他函数内部变量的函数。 在JS中,只有函数内部的子函数才能读取局部的变量,因此可以把...1.内存消耗大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄漏; **解决方法:...
  • 之前一直模模糊糊记得,let解决了某个闭包问题,想用时又不敢肯定,今天终于遇到这个问题了,那我们就一起来分析一下,什么是let,let有什么作用,以及,他是如何解决闭包的,当然,也顺便好好聊聊闭包。 1、闭包 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 427
精华内容 170
关键字:

如何解决闭包问题