精华内容
下载资源
问答
  • 闭包的理解
    千次阅读
    2022-04-04 16:06:38

    (此号文章均为个人学习理解,不一定正确)
    1、闭包是什么?
    闭包现象是指返回嵌套函数作为一个闭包,但可在函数之外访问函数局部变量的现象
    2、闭包原理:
    函数执行后为什么还能访问函数定义的变量呢?因为其返回为嵌套函数,函数__ closure 属性负责闭包绑定,闭包后将嵌套函数操作结果存在 closure __属性中,cell 对象的cell_contents 属性就是闭包中的自由变量,通过以下代码可查看变量

    print(x.__closure__[0].cell_contents)
    

    3、闭包函数结构及调用方式:
    一般有外围函数、嵌套函数,且外围函数以嵌套函数名作为返回

    def func():
    	a = 1
    	def sub_func():
    		nonlocal a
    		a += 1
    		print(a)
    	return sub_func
    	
    

    调用方式:

    f = func()
    f()
    

    4、闭包使用场景
    闭包后,外围函数的局部变量具有记忆功能,可以保留上一次调用的结果,避免使用全局变量(全局变量不容易排查)
    例如

    def funX():
        x = 5
        def funY():
            nonlocal x
            x += 1
            return x
        return funY
    
    a = funX()
    print(a())
    print(a())
    print(a())
    

    运行结果:

    6
    7
    8
    
    更多相关内容
  • JavaScript 闭包理解

    2022-04-16 20:30:27
    闭包就是能够读取其他函数内部变量的函数,因为 JS 中,只有函数内部的子函数才能读取局部变量,因此闭包的本质:就是在一个函数内部创建一个函数,创建的函数可以访问到当前函数的局部变量 1、闭包的特点: 1、函数...

    闭包就是能够读取其他函数内部变量的函数,因为 JS 中,只有函数内部的子函数才能读取局部变量,因此闭包的本质:就是在一个函数内部创建一个函数,创建的函数可以访问到当前函数的局部变量

    1、闭包的特点:

    1、函数嵌套函数

    2、函数内部可以引用函数外部的参数和变量

    3、参数和变量不会被垃圾回收机制回收

    2、闭包的用途:

    1、通过在外部调用闭包函数,可以在函数外部访问到函数内部的变量

    2、使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收

    以下是两个代码例子(方便理解)

    function fn(){
        var num = 1;
        return function(){
            return num;
        }
    }
    
    var fn1 = fn();
    console.log(fn1());//1
    

    以上代码中,fn()中的返回值是一个匿名函数,这个函数在fn()作用域中,使用它可以访问到fn()作用域下变量num的值,然后将这个值作为返回值赋给全局变量fn1,这样就实现了在函数外部访问函数内部的变量

    function fn(){
        var num = 1;
        return function(){
            var n = 0;
            console.log(++n);
            console.log(++num);
        }
    }
    
    var fn1 = fn();
    fn1();// 1 2
    fn1();// 1 3
    fn1();// 1 4
    

    以上代码中,fn()中的返回值是一个匿名函数,这个匿名函数被赋给了fn1,因为当一个函数执行结束后,函数和它里面的变量都会被摧毁掉。而匿名函数中访问了fn()里的变量num,所以变量num不会被销毁,而fn1()执行结束后,fn1()和里面的变量n都会被销毁,只剩下变量num留在内存中,这就实现了在函数执行结束后,使变量继续保留在内存中。

    3、循环使用闭包解决var定义函数的问题(面试题)

    //每隔1s输出一个i
    for (var i = 1 ; i <= 5 ; i++) {
        (function(i){
            setTimeout(function timer(){
                console.log(i);
            },1000*i)
        })(i)
    }
    //输出 1 2 3 4 5 
    
    //同时输出1 2 3 4 5
    for (var i = 1 ; i <= 5 ; i++) {
        (function(i){
            setTimeout(function timer(){
                console.log(i);
            },1000)
        })(i)
    }
    //输出 1 2 3 4 5 
    

    4、闭包优点

    ①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突

    ②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)

    ③匿名自执行函数可以减少内存消耗

    5、闭包缺点

    ①被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;

    ②其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

    参考文章:JS中的闭包

    展开全文
  • 本篇文章给大家详细分析了javascript变量提升和闭包的相关知识点,对此有兴趣的朋友可以参考下。
  • 浅谈js闭包理解

    2020-10-17 05:54:49
    主要介绍了对js闭包理解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • js闭包理解.pdf

    2021-09-13 14:57:54
    js闭包理解.pdf
  • 闭包理解

    2021-03-12 19:22:45
    刚学过的闭包,分享一下闭包理解 1.什么是闭包闭包就是一个函数,也可以说闭包是一个引用关系,可以理解为一个作用域可以访问另一个函数的局部变量。 代码: function fn() { var num = 10; ...

    闭包

    刚学过的闭包,分享一下闭包的理解
    1.什么是闭包?
    闭包就是一个函数,也可以说闭包是一个引用关系,可以理解为一个作用域可以访问另一个函数的局部变量。
    代码:

    			function fn() {
    				var num = 10;		
    				function fun() {
    					console.log(num);			
    				}
    				fun();
    			}
    			fn();
    

    函数调用后,运行结果为10;
    可以理解为 fun函数内部作用域访问到了fn函数内部的私有变量num,fn函数调用后,访问到了内部的局部变量。
    这就引出了闭包产生的条件。
    2.闭包的产生条件?
    a.函数的嵌套;
    b.内部函数 引用外部函数的局部变量;
    c.调用外部函数;
    3.闭包的作用
    a. 延长外部函数变量对象的生命周期(也可以认为延伸了变量的作用范围);
    b. 让函数外部可以操作(读写)到函数内部的数据(变量/函数),通过闭包间接的操作;
    c.注意: 浏览器为了性能后期将外部函数中不被内部函数使用的变量清除了;
    一段代码当中 究竟存在几套闭包机制 取决于外部函数调用了几次

    代码块一

      function fn() {
          var a = 0;
          function fn1() {
              a++;
              console.log(a)
          }
          return fn1;
        }
         var f = fn();
        f();
        f();
        f();
    

    解析:因为fn函数只调用了一次,创建了一次执行环境,后续的执行全在这一次创建的执行环境里,所以a++,也在原有的基础上增加。
    **所以输出结果为 1,2,3;**闭包机制只有一套
    代码块二

        function fn() {
          var a = 0;
          function fn1() {
              a++;
              console.log(a)
          }
          return fn1;
          }
       fn();
       fn();
       fn();
    
        
    

    解析:fn函数被调用了三次,每调用一次,就 创建一次新的执行环境,执行完成好进行销毁,所以每次调用a就从0开始++,所以输出结果为1,1,1;闭包机制有三套
    3.常见的闭包
    a. 将函数作为另一个函数的返回值;
    b. 将函数作为实参传递给另一个函数调用;
    c. 使用闭包实现私有方法操作独立的私有属性;

    看如下代码

    functionc fn(){
              var num =10;
              function fun(){
              console.log(num);
             }
             return fun;
    }
    var f = fn();
    console.log(f);
    console.log(f());
    

    将函数作为另一个函数的返回值;
    解析

    var f =fn();
    fn();//fn 运行 返回值是fun函数
    var f =function fun(){
       console.log(num);
    }
    

    所以console.log(f)打印出来的是 10
    因为 fun函数没有返回值,先运行一遍fun函数,再打印出fun函数的返回值;所以console.log(f());打印出来的值是 10,undefined

    4.闭包的生命周期

    	1. 产生: 在嵌套内部函数定义完时就产生了(不是在调用),外部函数调用的时候;
    	2. 死亡: 在嵌套的内部函数成为垃圾对象时;
    

    5.闭包的缺点和解决(内存泄漏和内存溢出)

    1. 内存泄漏 : 内存无法释放; 	
      
    2. 内存溢出 : 内存被撑爆; 	
      
    3. f = null;  解决方式;让闭包机制清除,必须删除外部函数调用的时候生成的(定义的那个对应内部函数);
      

    6.闭包面试题
    代码段1

    var name = "The Window";
    			var object = {
    				name: "My Object",
    				getNameFunc: function() {
    
    					return function() {
    						return this.name;
    					};
    				}
    			};
    			console.log(object.getNameFunc()());
    

    解析

    //解析
    			var f = object.getNameFunc();
    			var f = function() {
    				return this.name;
    			}
    			f();
    
    			function() {
    				return this.name;
    			}(); //相当于立即执行函数 this指向的是window
    

    此题没有用到闭包
    所以输出结果为 The Window
    代码段2

    var name2 = "The Window";
    			var object2 = {
    			   name2: "My Object",
    			   getNameFunc: function () {
    			       var that = this;
    			       return function () {
    			           return that.name2;
    			       };
    			   }
    			};
    			console.log(object2.getNameFunc()());
    

    解析
    典型的一个作用域可以访问另一个函数的局部变量。是闭包
    var that =this;
    这个this指的调用者object2对象,所以that也是object2对象,所以that.name2指的是object2的name属性。输出结果为 My Object

    展开全文
  • JavaScript之闭包理解

    千次阅读 2020-07-14 17:23:20
    JavaScript之闭包理解 闭包(Closure)是JavaScript学习过程中一个非常重要的问题 闭包和执行上下文和作用域链有着千丝万缕的关系。闭包是指有权访问另一个函数作用域的变量的函数(JavaScript高级程序设计(第三版...

    JavaScript之闭包理解

    闭包(Closure)是JavaScript学习过程中一个非常重要的问题

    闭包和执行上下文和作用域链有着千丝万缕的关系。闭包是指有权访问另一个函数作用域的变量的函数(JavaScript高级程序设计(第三版)P178)

    闭包是一个函数,对闭包的一个理解可以是所在的执行上下文已经出栈,但是仍然访问了其所在的执行上下文变量对象的函数

    这里所指的所在的执行上下文指的是闭包函数对应的执行上下文,而不是闭包本省所对应的执行上下文

    来一个简单的例子

    function A(){
    	var a = 2;
        function B(){
    		console.log(a);
        }
        return B;
    }
    A()();
    

    那么他的执行上下文栈行为是这样的

    /*伪代码*/
    // 代码执行时最先进入全局环境,全局上下文被创建并入栈
    ECStack.push(globalContext);
    // A 被调用,A 函数上下文被创建并入栈
    ECStack.push(<A> functionContext);
    // A 执行完毕,A 函数上下文出栈
    ECStack.pop();
    // B 被调用,B 函数上下文被创建并入栈
    ECStack.push(<B> functionContext);
    // B 执行完毕,B 函数上下文出栈
    ECStack.pop();
    // 代码执行完毕,全局上下文出栈
    ECStack.pop();
    

    我们都知道,JavaScript 拥有自动的垃圾回收机制,当一个值失去引用的时候,垃圾回收机制会根据特殊的算法找到它并将其回收。

    函数的执行上下文在出栈后,其变量对象会失去引用等待被回收,而闭包的存在会阻止这一过程,因为闭包的作用域链包含了其所在执行上下文的变量对象。

    通过上面的代码可以看出,在B函数执行的时候,A的上下文已经出栈了,按照JavaScript的垃圾回收机制,A上下文的变量对象失去引用后会被垃圾回收机制回收,但是由于B上下文作用域链包含了A上下文的变量对象,所以A上下文的变量对象不会被垃圾回收机制回收。

    我们知道函数作用域是在函数被定义(声明)的时候确定的。每一个函数都会包含一个[[scope]]内部属性,在函数被定义的时候,该函数的[[scope]]属性会保存其上层上下文的变量对象,形成包含上层上下文变量对象的层级链。

    那么刚刚的代码上下文应该是这样的,在创建的时候

    B.[[scope]]=[AContext.VO,globalContext.VO]
    

    在B被调用的时候,其执行上下文会被创建并入栈,此时会生成变量对象并将该变量对象添加进作用域链的顶端,并将[[scope]]添加进作用域链

    BContext.Scope = [BContext.VO].concat(B.[[scope]])
    =>
    BContext.Scope = [BContext.VO,AContext.VO,globalContext.VO]
    

    可见,B上下文的作用域链包含了A上下文的变量对象,并且由于B访问A中的变量,阻止了A上下文的变量对象被垃圾回收机制回收。

    看一个面试题经常会遇到的一个关于闭包的很经典的题目

    var arr = [];
    for (var i = 0; i < 3; i++) {
        arr[i] = function () {
            console.log(i);
        };
    }
    
    arr[0]();//3
    arr[1]();//3
    arr[2]();//3
    

    在 arr[0] 函数执行之前,我们可以知道,全局上下文的变量对象如下所示

    globalContext = {
    	VO:{
    		arr:[],
            i=3
        }
    }
    

    在 arr[0] 被调用执行时,其作用域链在函数上下文的创建阶段被创建,其作用域链如下

    arr[0]Context = {
        Scope: [arr[0]Context.VO, globalContext.VO]
    }
    

    arr[0]函数会在自身变量对象中寻找i(arr总没有i),所以会向上找,找到全局上下文变量对象中的i,所以输出3

    那么如何解决闭包

    立即执行函数

    var arr =  [];
    for(var i = 0; i < 3; i++){
    	arr[i] =  (function(j) {
            return function(){
    			console.log(j);
            }
        })(i)
    }
    arr[0]();//0
    arr[1]();//1
    arr[2]();//2
    

    ES6中的let

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

    setTimeout

    也还可以利用setTimeout的第三个参数

        var arr = [];
        for(var i = 0; i < 3; i++){
            arr[i] = setTimeout(function(i){
                console.log(i);
            },0,i)
        }
    
    展开全文
  • 闭包理解及面试题目

    2019-04-22 17:42:40
    1 闭包理解 在A函数里面创建一个函数B,则B就是闭包 2 闭包的作用 (1)js作用域,函数内部可以调用函数外部的变量,反之不行,如果需要,则可以使用闭包 (2)一般情况下, 函数执行完后,局部活动对象就会...
  • js闭包 • 每个函数都有一个包含词法环境的执行上下文,它的词法环境确定了函数内的变量赋值以及对外部环境的引用。看上去函数“记住”了外部环境,但其实上是这个函数有个指向外部环境的引用。这就是“闭包”的...
  • 闭包理解及应用场景

    2022-01-25 09:25:55
    js闭包
  • js闭包理解之倒计时

    2014-07-11 15:07:59
    网上大多只是讲解js闭包的大概意思和小例子,但真实用于项目中又该怎么用呢。这个例子真实的告诉大家在项目中的用法
  • JS闭包理解

    2018-11-21 16:54:57
    在 JavaScript 中,由于只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数” 所以,在本质上,闭包就是将函数内部和外部连接起来的一座桥梁。 四、闭包的用途  ...
  • PHP中的闭包理解

    2021-05-08 00:46:38
    PHP中的闭包理解没有名字的函数叫"匿名函数",这个很好理解.但单纯的匿名函数不是闭包,只有当匿名函数绑定了外部变量的时候,此时才形成了一个"闭包".在JS中,闭包被广泛使用,一方面由于JS的垃圾回收机制,一方面由于JS...
  • js闭包理解

    2013-04-17 07:27:55
    • 简介 • 基于对象的属性名解析 o 值的指定 o 值的读取 • 标识符解析、执行环境和作用域链 o 执行环境 o 作用域链与 [[scope]] o 标识符解析 • 闭包
  • 作用域和闭包理解

    2020-09-10 18:31:59
    作用域 作用域为可访问变量,对象,函数的集合。...闭包可以让你从内部函数访问外部函数作用域。 function makeFunc() { var name = "Mozilla"; function displayName() { alert(name); } return displayName; }
  • C++闭包理解和应用

    2021-03-31 17:09:20
    闭包可以理解为函数加状态的组合。同时用更简练的语法和较少的代码表述。其中Lambda表达式更好的体现了这种风格。 在C++中示例如下: int ret = 0; //实现位左移1位即*2 int y = 2; auto f = [=](int x) ->...
  • python 闭包理解

    2019-09-24 10:56:19
    网络上大家对闭包的定义一般是说“能够读取外部函数变量的函数”,一直感觉这个有点理解上不是那么自然。这里以python3为例,通过简单的实践解析下它里面的闭包到底是个什么样的东西。 先来个简单的例子: def func_...
  • 闭包理解

    2022-02-20 22:03:32
    1、理解 简单就是定义在一个函数内部的函数,可以使用其他函数的变量。 闭包是一种保护私有变量的机制,函数执行时形成私有作用域,保护私有变量不受外界影响。 内部函数可以使用外部函数的参数和变量,函数和...
  • Groovy闭包理解

    千次阅读 2020-10-06 16:13:16
    闭包理解 闭包(Closure)是很多编程语言中很重要的概念,那么Groovy中闭包是什么,官方定义是“Groovy中的闭包是一个开放,匿名的代码块,可以接受参数,返回值并分配给变量”,简而言之,他说一个匿名的代码块...
  • 闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是 ECMAScript 规范给的定义,如果没有实战经验,很难从定义去理解它。 在接触一个新技术的时候,我首先会做的一件事就是...
  • const [ count, setCount ] = useState( 0 ) console.log( 'redner...' ... // btnClick && btnClick() } react hooks 每个状态都会形成一个闭包环境, 如果想让多个闭包之前共享变量,可以用单例模式或者useRef传值方式
  • 看完定义后,我陷入了沉思…确实,如果之前没有接触过闭包或者对闭包理解的话,这个定义着实有点让人上头。 下面让我们先看几个示例,在了解闭包的实际应用后,再去理解这个定义,就不会那么晦涩难懂了。 示例 Go ...
  • js中对闭包理解

    千次阅读 2022-03-17 14:46:51
    闭包的解释一:就是上级作用域内变量的生命周期,因为被下级作用域内引用,而没有被释放。就导致上级作用域内的变量,等到下级作用域执行完以后才正常得到释放。 闭包的解释二:它是这样工作的,无论何时声明新函数...
  • js中闭包理解

    2021-08-30 18:36:22
    对于闭包二字, 我们常常听说, 可能更加知道面试的时候, 面试官必问知识点之一 在MDN 中, 对闭包是这样定义的 ...要想理解闭包, 必然需要理解js的变量作用域: 全局变量和局部变量 我们都知道, 在函数内部

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 86,257
精华内容 34,502
关键字:

闭包的理解

友情链接: ygovcv.rar