精华内容
下载资源
问答
  • js解决闭包问题

    千次阅读 2019-03-09 11:31:22
    解决闭包问题 function test() { var arr = []; for(var i = 0; i; i++) { arr[i] = function() { document.write(i + " "); } } return arr; } var myArr = test(); for(var i = 0;i ; i++) { myArr[j]...

    1:立即执行函数
    此类函数没有声明,在一次执行过后立即释放。

    语法格式
    1:(function (){}())
    2: 传参数:
    (function (a,b,c) {}(1,2,3))
    3: 只有表达式才能被执行符号执行
    执行符号
    function test (){} () 不行
    (function test () {}()) 可以 此时函数名test可以直接忽略 就演变成下面的形式。
    (function (){}())

    解决闭包问题

    function test() {
    	var arr = [];
    	for(var i = 0; i< 10; i++)
    	{
    	arr[i] = function() {
    	 	document.write(i + " ");
    	}
    	}
    	return arr;
    }
    var myArr = test();
    for(var i = 0;i < 10; i++)
    {
    myArr[j]();
    } 
    

    很多人会认为打印的是0-9,但是并非这样,打印出来的是10个10

    分析
    test函数的for循环中的每一个函数function都会与test形成闭包,都能使用test 的执行期上下文。当myArr[j]函数执行时,test已经执行完毕,而i是在test里面定义的,test执行完毕时i已经是10,所以每个myArr[j]执行时 i 都是10.这样打印出来的就是10个10。
    注意
    函数在定义时,是不会看函数体里面是什么的;只有当函数执行时,才会看函数体里面的内容。

    要想打印0-9,怎样解决呢?就要利用立即执行函数,用闭包解决闭包

     function test() {
    	var arr = [];
    	for(var i = 0; i< 10; i++)
    	{
    	 (function (j) {
    	arr[j] = function(){
    	document.write(j + " ");
         }
       }(i))
        // arr[i] = function(){
        //     document.write(i + "");
    	
        // }
        }
        return arr;
        }
    
    
    var myArr = test();
    for(var j = 0;j < 10; j++)
    {
    myArr[j]();
    } 
    

    (function (j) {
    arr[j] = function(){
    document.write(j + " ");
    }
    }(i))
    这一段代码为立即执行函数,将i作为实参传入,这样i的值就被保存到j中,每一个myArr[j]执行时,会产生一个执行期上下文,里面的j都是相互独立的,它们分别保存了每一次 i 的值。这样问题就解决了。

    展开全文
  • 立即执行函数解决闭包问题 立即执行函数的定义 定义 : 此类的函数没有声明,在一次执行过后释放(被销毁),适合做初始化工作,针对初始化功能的函数,只想让他执行一次的函数,立即执行函数也有参数,也有返回值...

    立即执行函数解决闭包问题

    立即执行函数的定义

    1. 定义 : 此类的函数没有声明,在一次执行过后释放(被销毁),适合做初始化工作,针对初始化功能的函数,只想让他执行一次的函数,立即执行函数也有参数,也有返回值,也能预编译。
    2. 立即执行函数有两种写法
     (function(){}());  w3c建议使用这一种
     (function(){})();
    

    补充:

    1. 只有表达式才能被执行符号执行
    2. 能被执行符号执行的表达式,这个函数的名字就会被自动忽略(放弃自己的名字)
    3. 能被执行符号执行的表达式基本上就是立即执行函数。
    4. 函数声明和函数表达式是两个东西,虽然都能定义函数。
    5. 一元正负号 + / -
    + function test(){}  
    	// 加了正负号就是趋势上把他转换成数字了,也就是说转化成为表达式了,转化成表达式了就能被执行了,所以这样变成了立即执行函数
    * / /   乘号和除号不行,&&||  前面放东西也可以
    

    闭包问题

     function test(){  //定义一个函数
    	var arr = [];  // 定义一个空数组
    	for(var i=0; i < 10; i++){ 
    	//丰满空数组,让这个空数组添加十条数组,每一条都是一个function(){};
    			arr[i] = function(){
    			//随着for循环的i在变化,数组的i也在变,arr的每一次都等于一个全新的函数
    				document.write('i + " " ');
    				
    }
    }
    		return arr;//把arr返回到外部
    }
    
    
    	var myArr = test();
    	for(var j = 0; j < 10; j++){
    	//利用for 循环,分别执行十个函数体,函数里面定义了 document.write
    	//for循环是为了 打印这个数组,否则的话需要自己写很多次
    //myArr[0]();
     //myArr[1]();
      
    			myArr[j]();
    	}
    	
    
    1. 首先上面的代码我们的初衷是想实现 打印出1 - 10 ;,可是我们打印出来的却是是个 十个10; 这就是闭包产生带来的后果,下面我们来分析一下产生闭包的原因和解决的办法
      我们 第一个 var i = 0 的for循环 执行了10次,产生了10个彼此独立的函数,我们又把函数保存到了数组中,并且把数组return ,这样这十个函数与test一起产生了闭包
      既然产生了闭包,那么访问的test里面的变量,都是同一套,test产生了arr 和 i ,而这是个函数在外边要访问 i 变量 ,其实访问的都是同一个 i 。
      为什么会打出10个十那,i 不是 < 10吗?
      第一个 i= 0 , 当 i 转到 9 时候,执行 i++, 这时 i= 10 , 结束时 return arr ,返回 arr 。这十个 函数都是为了打印 i 的,那么在外部访问 i 的时候,i = 10,所以打印的都是10.
    理解过程:在这个函数体中,当 arr[0] 时,document.write(i)的 i 是不变的,还是 i,
    等函数保存到外部之后,等执行的时候,才会去找 i 的值。
    这个赋值语句中,arr[0] = 函数;把一个函数体或者说是一个函数引用赋给数组的当前
    位,数组的当前位需要马上被索取出来的(数组现在是当前第几位,我们是知道的,
    因为这个是执行语句),当 for(var i = 0)时,arr[i]会变成 arr[0],但是这个 i 跟函数体
    里面的 d.w(i+“”)里面的 i 是没有关系的,因为函数体 function(){}不是现在执行,
    不会在意函数里面写的是什么,不是现在执行那么里面的 document.write 不会变成现
    实的值,不是现在执行就是函数引用(函数引用就是被折叠起来的,系统不知道里
    面写的是什么)
    在执行 myArr[j]();的时候,系统才会读 document.write(i +””)里面的语句
    在定义函数的时候是不看里面的,在执行的时候才看
    
    如果我们想让这个函数打出来的是 0,1,2,3,4,5,6,7,8,9 ,那我们利用立即执行函数来解决这个问题。
    
    	function test (){
    	 var arr = [];
    	 for (var i = 0; i < 10; i ++){
    	 (function (j) {
    		arr[j] = function () {
    		document.write( j + “ ”);
    }
    }(i));
    			return arr;
    }
    	var myArr = test();
    	for (var j = 0; j < 10; j ++){
    	 myArr[j]();
    }
    
    

    理解过程:相当于在 for 循环里面有十个立即执行函数 function(j){}
    在第一圈 i 是 0,j 也是 0,function(){document.write( j + “ ”)}拿着 j=0,进行循环
    的第二圈 i 是 1,又有了一个新的 j 是 1,反复循环
    形成了十个立即执行函数,有十个 j 对应

    闭包的防范:闭包会导致多个执行函数共用一个公有变量,如果不是特殊需要,应尽量防止这种情况发生。

    展开全文
  • 闭包&解决闭包问题

    2020-09-13 11:37:47
    2、函数与函数所依赖的上下文环境组成闭包问题。 3、闭包指的是:能够访问另一个函数作用域的变量的函数。清晰的讲:闭包就是一个函数,这个函数能够访问其他函数的作用域中的变量。 var arr = []; for (var i = 0; ...

    1、函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包(closure)。
    2、函数与函数所依赖的上下文环境组成闭包问题。
    3、闭包指的是:能够访问另一个函数作用域的变量的函数。清晰的讲:闭包就是一个函数,这个函数能够访问其他函数的作用域中的变量。

    var arr = [];
    for (var i = 0; i < 10; i++) {
        arr[i] = function () {
            console.log(i);
        };  
    }
    

    上面的代码构成了闭包问题,var声明的变量没有块级作用域

    解决闭包问题:
    1、使用let声明变量,因为let声明的变量有块级作用域

    var arr = [];
    for (let i = 0; i < 10; i++) {
        arr[i] = function () {
            console.log(i);
        }; 
    }
    

    2、使用IIFE立即执行函数

    for (var i = 0; i < 10; i++) {
        //IIFE
        arr[i] = (function (num) {
            //num-->0,1,2,3...
            return function () {
                console.log(num);
            }
        })(i);
    }
    

    3、如果有循环,可以使用数组的forEach

    展开全文
  • let解决闭包问题

    2020-06-26 19:09:58
    闭包在Javascript里面是很重要的一个环节,下面看一个简单的例子 var f = function(){ var i = 0; return function(){ i++; console.log(i) } } var s = f(); s();//1 s();//2 s();//3 ...

    闭包在Javascript里面是很重要的一个环节,下面看一个简单的例子

    var f = function(){
    			var i = 0;
    			return function(){
    				i++;
    				console.log(i)
    			}
    		}
    		var s = f();
    		s();//1
    		s();//2
    		s();//3
    

    闭包简单来说,就是函数f内的变量 i 被外部函数s引用到了,而且i不能释放,一直在内存中,形成了闭包

    <ul>
    		<li>1</li>
    		<li>2</li>
    		<li>3</li>
    		<li>4</li>
    	</ul>
    	window.onload = function(){
    			var lists = document.getElementsByTagName('li');
    			for(var  i = 0 ; i< lists.length;i++){
    				lists[i].onclick = function(){
    					console.log(i)//点击时都会打印4
    				}
    			}
    		}
    

    let是es6里面的,那它与闭包又有什么关系呢?看一下let如何解决

    <ul>
    		<li>1</li>
    		<li>2</li>
    		<li>3</li>
    		<li>4</li>
    	</ul>
    	
    		window.onload = function(){
    			var lists = document.getElementsByTagName('li');
    			for(let  i = 0 ; i< lists.length;i++){
    				lists[i].onclick = function(){
    					console.log(i)//点击时都会打印0,1,2,3
    				}
    			}
    		}
    ```由于es6里面是有块级作用域的。
       在每次遍历之前就会生成一个块级的作用域,而每个作用域互不干扰
       也就是会生成lists.length个这种作用域来分别保存变量i的值,作为局部变量
     既然是局部变量,那么 点击第一个li,在执行的时候根据作用域链的规则 访问的肯定是当前作用域里的 i 
    即:点击第一个li访问到了 第一个作用域(局部) 里的变量
    这样看的话,是符合闭包的概念的,当然也是闭包
    ## 为什么let可以解决闭包?
    var声明的变量,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变。
    
    let声明的变量,仅在块级作用域内有效,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量。而JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。
    
    
    展开全文
  • ES6 let解决闭包问题

    2020-12-09 16:42:12
    ES6 let解决闭包问题 ES6 let let 是 ES6 新增的命令,用来声明变量 let 用法和 var 类似,区别: var 声明变量存在变量提升,let 不存在变量提升 var 可以重复声明变量,let 不可以重复声明 let 声明变量存在块...
  • js闭包问题以及解决办法

    千次阅读 2019-02-21 14:38:28
    个人理解闭包的产生主要就是:一切最外部的函数比里面的函数先执行,必然产生闭包闭包会导致原有的作用域链不释放,造成内存泄漏   例子1 解析:实现上现在的demo保存的是function b() a执行之后就销魂了...
  • 本文通过举例,由浅入深的讲解了解决js函数闭包内存泄露问题的办法,分享给大家供大家参考,具体内容如下 原始代码: function Cars(){ this.name = "Benz"; this.color = ["white","black"]; } Cars.prototype....
  • 闭包问题解决

    万次阅读 2018-01-23 19:12:46
    闭包的形成 当内部函数被保存到外部时,会形成闭包闭包会导致原始作用域链不释放,造成内存泄漏(占用); 例如: function test(){ var arr = []; for(var i = 0; i ; i++){ arr[i] = ...
  • 用立即执行函数 解决闭包问题

    千次阅读 2014-07-06 17:10:18
    这个就是个经典的闭包问题,由于闭包,addEventListener里面的匿名函数中的变量i一直保持着外部变量i的引用(也就是说无论是匿名函数还是匿名函数外的函数,就要变量i的值变了,都会变) ,所以等循环结束时,i 的值...
  • 作者:虫哥写代码,来自原文地址 看到标题“闭包”很多人会觉得懵逼包括我在内,之前对闭包有所听闻但始终无法准确全面的了解。...引入闭包解决方案;升华闭包概念理解。废话少说直接步入正题。   还原
  • 什么是闭包? 可以把闭包简单理解成“定义在一个函数内部的函数”。 即函数嵌套函数,内部函数可以访问外部函数的变量 为什么要使用闭包? javascript语言的特殊处就是函数内部可以读取全局变量。我们有时候需要...
  • 很完整的一个动态循环给onclick赋值的小例子,解决闭包问题,希望对你会有帮助,呵呵
  • js解决闭包问题现象

    千次阅读 2018-09-13 10:12:43
    &lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt;  &lt;meta charset="UTF-8"&gt;  &lt;title&gt;Document&lt;...ul
  • 上述代码执行后毫无疑问是10,es6之前解决闭包问题的办法通常是这样的: var ary=[]; for(var i=0;i;i++){ (function(j){ //隐式执行var j=i; ary[j]=function(){ ...
  • <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ...meta name="viewport" content="width=device-width, initial-scale=1.0">...Do.
  • React Hooks典型闭包问题 const Demo = () => { const form = Form.useForm({model: { input3: "32323" }}); const [searchParams, setSearchParams] = useState<any>(form.getModel()); const onSubmit...
  • 闭包,立即执行函数解决闭包问题

    千次阅读 2018-07-29 19:19:11
    一个简单的demo 讲述闭包 所谓闭包,简单来说就是函数内部的某个值被保存到函数外部。通常用return直接保存。 function test() { var arr = []; for(var i = 0; i &amp;lt; 10; i++){ arr[i] = function ()...
  • javascript 常见的闭包问题解决办法,需要的朋友可以参考下。
  • js闭包问题

    2017-02-27 16:28:05
    js的闭包1.变量的作用域 要理解闭包,首先必须理解javascript特殊的变量作用域。 变量的作用域无非就是两种:全局变量和局部变量。 javascript语言的特殊之处,就是在于函数内部可以直接读取全局变量。 举例来...
  • 今天就闭包问题,自己做一个简单的小结。 什么是闭包 定义和用法:当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了其父函数内部的其它变量,如果返回的这个函数在外部被执行,就产生了闭包。 表现...
  • 闭包问题解决(立即执行函数)
  • export const MyComponent = props=>{ const [message,setMessage] = useState('inittial message') const [seconds,setSeconds] = useState(0) const secondsRef = useRef(seconds) useEffect(()=>...
  • 之前看视频的时候学到闭包问题,想自己试试就写了一下var arr = [1,2,3,4,5,6,7,8,9];for(let i = 0 ; i &lt; arr.length ; i ++ ){ console.log(i); setTimeout(function(){ console.log(i); },10);}输出结果...
  • 【转载】解决闭包的9种方法

    千次阅读 2017-01-07 11:28:43
    1.正确的说,应该是指一个闭包域,每当声明了一个函数,它就产生了一个闭包域(可以解释为每个函数都有自己的函数栈),每个闭包域(Function 对象)都有一个 function scope(不是属性),function scope内默认有个名为Global...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 70,174
精华内容 28,069
关键字:

如何解决闭包问题