JS函数(二)闭包

news/2024/7/15 21:02:46

有不少开发人员总是搞不清匿名函数和闭包这两个概念,因此经常混用。闭包是指有权访问另一个函数作用域的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。

     function createComparisonFunction(propertyName){
        return  function(object1,object2){
            var value1=object1[propertyName];
            var value2=object2[propertyName];

            if(value1<value2){
               return -1;
            }else if(value1>value2){
                  return 1;
            }else{
                  return 0;
            }
        };
   }

在这个例子中,value1和value2这两行代码是内部函数(一个匿名函数)中的代码,这两行代码访问了外部函数中的变量propertyName。即使这个内部函数被返回了,而且是在其他地方被调用了,但它仍然可以访问变量propertyName。之所以还能够访问这个变量,是因为内部函数的的作用域链中包含createComparisonFunction()的作用域。要彻底搞清楚其中的细节,必须从理解函数被调用的时候都会发生什么入手。
当某个函数被调用时,会创建一个执行环境及相应的作用域链。然后,使用arguments和其他命名参数的值来初始化函数的活动对象。但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位,·····直至作为作用域终点的全局执行环境。
在函数执行过程中,为读取和写入变量的值,就需要在作用域链中查找变量。来看下面的例子。

   function compare(value1,value2){
          if(value1<value2){
               return -1;
           }else if(value1>value2){
               return 1;
           }else{
                return 0;
           }
        }
        var result=compare(5,10);

以上代码先定义了compare()函数,然后又在全局作用域中调用了它。当调用compare()时,会创建一个包含arguments、value1和value2的活动对象。全局执行环境的变量对象(包含result和compare)在compare()执行环境的作用域中则处于第二位。图7-1展示了包含上述关系的compare()函数执行时的作用域链
图7-1这里写图片描述
后台的每个执行环境都有一个表示变量的对象——变量对象。全局环境的变量对象始终存在,而像compare()函数这样的局部环境的变量对象,则只在函数执行的过程中存在。在创建compare()函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[scope]]属性中。当调用compare()函数时,会为函数创建一个执行环境,然后通过复制函数的[[scope]]属性中的对象构建起执行环境的作用域链。此后,又有一个活动对象(在此作为变量对象使用)被创建并被推入执行环境作用域链的前端。对于这个例子中compare()函数的执行环境而言,其作用域链中包含两个变量对象:本地活动对象和全局变量对象。显然,作用域链本质上是一个指向变量对象的指针列表,它只引但不实际包含变量对象。


http://www.niftyadmin.cn/n/1869670.html

相关文章

JS学习之Array类型(一)

ECMAScript数组的每一项可以保存任何类型的数据。也就是说&#xff0c;可以用数组的第一个位置来保存字符串&#xff0c;用第二位置来保存数值&#xff0c;用第三个位置来保存对象&#xff0c;以此类推。而且&#xff0c;ECMAScript数组的大小是可以动态调整的&#xff0c;即可…

JS学习之工厂模式

一。 虽然Object构造函数或对象字面量都可以用来创建单个对象&#xff0c;但这些方式有个明显的缺点&#xff1a;使用同一个接口创建很多对象&#xff0c;会产生大量的重复代码&#xff0c;为解决这个问题&#xff0c;可以使用工厂模式的一种变体。 二。 ECMAScript中无法创…

JS学习之基本概念

一.区分大小写 ECMAScript中的一切(变量、函数、操作符)都区分大小写。这意味着。变量名test和变量名Test分别表示两个不同的变量&#xff0c;而函数名不能使用typeof,因为它是一个关键字&#xff0c;但是typeOf则完全可以是一个有效的函数名 二.标识符 所谓标识符。就是指变…

想学python怎么学习_老男孩教育:如何学习好Python?Python怎么学习?

Python是一种脚本语言&#xff0c;内核属于纯C的性能表达&#xff0c;主要性能消耗在脚本的实时的编译之上。 相对比C语言来说&#xff0c;Python在表达的时候更加简单精炼一下&#xff0c;自然也会失去一定的性能问题&#xff0c;不过它完全能以快捷迅速的开发速度优势盖过某些…

JS学习之Array数组forEach方法

它只是对数组中的每一项运行传入的函数。什么意思&#xff1f;看例题说话 var arr[1,2,3,4,5]; arr.forEach(function(item){consolo.log(item);consolo.log("----"); } 结果如图 也就是说&#xff0c;forEach首先对arr数组中的第一项&#xff08;也就是1&#xf…

一文看懂web服务器、应用服务器、web容器、反向代理服务器区别与联系

我们知道&#xff0c;不同肤色的人外貌差别很大&#xff0c;而双胞胎的辨识很难。有意思的是Web服务器/Web容器/Web应用程序服务器/反向代理有点像四胞胎&#xff0c;在网络上经常一起出现。本文将带读者对这四个相似概念如何区分。 Web服务器概念与基本原理 Web服务器的历史…

jquery学习之选择器与过滤器

基本选择器 普遍选择器 * 所有的id选择器 #id类选择器 .class标签选择器 标签名群组选择器 #one,.two 取并集复合选择器 div#one 取交集子代或后代选择器 子代选择器 > 直接孩子后代选择器 空格 所有的后代body * body中的所有的后代元素兄…

NG、域名、https 获取不到header的自定义参数的值

自己项目遇到的一个问题&#xff0c;和我们的解决过程记录吧。 技术框架是spring boot&#xff0c;前端将token放在header里面&#xff0c;自定义一个参数&#xff0c;然后再后台通过request.getHeader("参数")获取&#xff1b; 1、我们在自己的本地和测试环境下是…