zoukankan      html  css  js  c++  java
  • 闭包工作原理

    闭包(Closure)是JavaScript语言中一个非常重要的特性

    在Javascript语言中,只有函数中的子函数才能引用函数中的变量,简单来说,闭包就是定义在函数中的函数,是函数内外部连接的桥梁

    闭包的意义是:当前作用域总是能够访问外部作用域中的变量;函数是唯一拥有自身作用域的结构,所以闭包的创建依赖于函数

    变量的作用域

    闭包是Javascript语言中的一个难点,理解闭包之前,先来理解一下变量的作用域

    全局变量、局部变量是变量的作用域仅有的两种形态;一般来说,全局变量可以在任意作用域中引用,而局部变量则只能在当前作用域中引用。先看如下代码所示

    var number = 1;
    var Get_Number = function ()
    {
    	console.log(number);
    };
    Get_Number();
    

    输出结果为1;这是一个全局变量,可以在任意作用域中引用。再看如下代码所示

    var Get_Number = function ()
    {
    	var number = 1;
    };
    console.log(number);
    

    var Get_Number = function ()
    {
    	var number = 1;
    };
    Get_Number();
    console.log(number);

    输出结果都为ReferenceError: number is not defined;这是一个局部变量,无法在外部作用域中引用该变量,运行该函数后也不能;这里需要注意的是,局部变量的声明必须使用var表达式,否则运行该函数后相当于声明了一个全局变量。代码如下所示

    var Get_Number = function ()
    {
    	number = 1;
    };
    Get_Number();
    console.log(number);
    

    输出结果为1;这里实际上是声明了一个全局变量

    引用局部变量

    正常来说,局部变量只能在函数中引用。先看如下代码所示

    var Get_Number = function ()
    {
    	var number = 1;
    	var Out_Number = function ()
    	{
    		console.log(number ++);
    	};
    	Out_Number();
    };
    Get_Number();
    

    输出结果为1;子函数可以引用当前作用域中的变量,这实际上是JavaScript语言中的一个特色结构——作用域链(Scope Chain)。既然子函数可以引用该变量,那么我们return子函数,是不是就可以在外部作用域中引用该变量了。代码如下所示

    var Get_Number = function ()
    {
    	var number = 1;
    	var Out_Number = function ()
    	{
    		console.log(number ++);
    	};
    	return Out_Number;
    };
    var r = Get_Number();
    r();
    

    输出结果为1;并且我们继续运行r(),输出值会递增——2、3、4、5,这个值被存储于内存中,这个Out_Number子函数正是我们要讨论的闭包

    闭包的使用

    闭包的两大作用,一个是读取函数中的变量,另外一个是将函数中的变量的值存储于内存中。先看如下代码所示

    var Get_Number = function ()
    {
    	var number = 1;
    	return {
    		plus: function ()
    		{
    			number ++;
    		},
    		out: function ()
    		{
    			return number;
    		}
    	};
    };
    
    var r = Get_Number();
    r.plus();
    r.out();
    

    返回值为2;2个闭包plus、out都维持着对Get_Number外部作用域的引用,在当前作用域中,只能通过这2个闭包访问Get_Number外部作用域。代码如下所示

    var Get_Number = function ()
    {
    	var number = 1;
    	return {
    		plus: function ()
    		{
    			number ++;
    		},
    		out: function ()
    		{
    			return number;
    		}
    	};
    };
    
    var r = Get_Number();
    r.change = function ()
    {
    	number = 0;
    };
    r.change();
    r.plus();
    r.out();
    

    返回值同上;r.change并没有改变Get_Number外部作用域中的变量number的值,它作用仅仅是声明或者覆盖了全局变量number

    闭包可以在函数外部改变函数中的变量的值,如果你把函数作为对象、闭包作为方法、局部变量作为私有属性使用,则会改变该变量的值;闭包还会把函数中的变量的值存储于内存中,对内存消耗很大,所以滥用闭包的结果就是影响网页性能,IE中则可能导致内存泄露
  • 相关阅读:
    审计 6 SSRF和任意文件读取
    审计5 文件包含漏洞
    审计4 XSS
    owasp Top 10 个人总结
    审计3(由安装引起的服务器沦陷)
    python批量爆破后台目录脚本
    python批量检测注入点脚本
    对VAuditDemo的审计<2>
    工作总结(一)
    使用vue upload 标签上传图片后端MultipartFile 为null
  • 原文地址:https://www.cnblogs.com/johnl/p/4849566.html
Copyright © 2011-2022 走看看