07 JSCORE function、作用域和闭包

正课:
1. ***Function

      重载

      匿名函数
2. *****作用域和作用域链
3. *****闭包

    

1. ***Function:
    什么是: js中一切函数都是对象
                函数对象是专门封装函数定义的对象。
    创建: 3种:(若为同名函数,后面的会替换前面的)
      1. 声明: function 函数名(参数列表){函数体; return 返回值;}
          何时: 只要一段代码被反复使用,都要先定义在一个专门的函数中,再反复调用函数即可——复用
             何时使用参数: 只要函数步骤中必须某些数据才能正常执行时,就要定义参数。
             何时使用返回值: 如果函数的调用者需要函数的执行结果时,函数就必须返回值。
         可被声明提前:

   ****声明提前(hoist): 在开始执行程序前,将所有var声明的变量和function声明的函数提前到*当前作用域*的顶部,集中创建。
         *******************赋值留在原地!*****************

      2. 函数直接量:
       var  函数名=function(参数列表){函数体; return 返回值;};
         不会被声明提前。
       何时: 只要不希望被声明提前时。
        揭示了: 函数名仅是一个普通的变量
                    函数定义其实是一个对象
                    函数名中仅保存了函数对象的地址——引用

   

    

    3. (比较罕见,所有形参必须放在引号中)用new:
var fun=
     new Function("参数1","参数2",...,"函数体; return 返回值")

     笔试: function compare(a,b){return a-b;}
              var compare=function(a,b){return a-b;}
              var compare=new Function("a","b","return a-b;");

***重载(overload):
  什么是: 相同函数名,不同参数列表的多个函数,在调用时,可根据传入参数的不同,自动选择对应的函数调用!
   为什么: 减轻调用者的负担,一个函数名,可执行多种操作
   何时: 一项任务,根据不同的参数,执行不同的操作流程时
   如何:   js语法不支持重载效果!!!!(因为js不允许多个同名函数同时存在,Java标识函数是函数名加列表)
      变通:  所有函数对象内,都自动内建了一个arguments对象
         arguments对象:
            专门保存传入函数的所有参数值的类数组对象
             类数组对象: (object like array)即长得像数组的对象
                vs 数组: 相同: 下标, length, for遍历
                             不同: 类数组对象是Object,不是Array,无法使用Array的API
                                     数组是Array类型,可以使用数组类型所有的API

  重载必须得用,运用了的有splice(),toString()......

   

   

    匿名函数:
    什么是: 函数创建时,不被任何变量引用的函数
    为什么: 节约内存
    何时: 如果一个函数只用一次,用完希望自动释放时

    如何:2种
        1. 回调callback: 将函数作为参数传递给另一个函数去调用  
            比如: arr.sort(function (a,b){return a-b});
                     str.replace(/reg/g,function(kw,$1,...){return ...})
        2. 自调: 创建函数后立刻调用自己!
            何时: 如果一段代码,不希望其中的变量造成全局 的污染,全局变量容易受到篡改,就将其放在匿名函数中
            为什么: 建立临时作用域!避免全局污染!
            如何:
               +function(参数列表){

                        函数体; return 返回值}();

        

       

2. *****作用域和作用域链
   作用域scope:
     什么是: 一个变量的使用范围——使用
                 本质上作用域是一个对象——存储
                     作用域中的变量都是对象的成员

     包括:2种

            1.全局作用域:(全局变量)随处可用,可反复使用——全局污染

            2.函数作用域:(局部变量)仅函数内使用,不可重复使用。

      函数的生命周期:

                   第一阶段:开始执行前:创建执行环境栈(数组):临时保存正在执行的函数的执行环境,向执行环境栈中压入第一个默认函数main();创建全局对象window

                   第二阶段:定义函数时:创建函数对象,封装函数定义;声明函数名变量,引用函数对象;函数对象的scope属性引用回,创建函数时的作用域;

                   第三阶段:调用函数时:ECS中压入一个新的元素(执行环境)记录新函数的调用;创建一个活动对象:函数作用域对象,保存本次函数调用用到的局部变量;ECS中的新执行环境元素,引用活动对象,活动中的parent属性引用函数的scope指向的父级作用域对象(即从活动对象指向window:全局作用域对象)。执行过程中优先使用活动对象中的局部对象,若无,就找parent,全局也无,则报错。

                   第四阶段:函数调用后:执行环境栈中本次函数的执行环境出栈,导致活动对象被释放,
     程序/函数的执行过程:
        1. 开始执行程序前:
            创建ECS(执行环境栈):
                依次保存每个调用的函数的执行环境
            在ECS中压入第一个全局执行环境(全局EC)
            创建window对象,全局EC引用window对象
            window就是全局作用域对象
        2. 开始执行程序:
            所有全局变量都保存在全局作用域对象window中
        3. 定义函数时:
            在全局添加函数名变量
            创建函数对象封装函数定义
            函数名变量引用函数对象
            函数对象中有一个scope属性,引用回创建函数时的作用域对象。通常都是window。
        4. 调用函数时:
            在ECS中压入一个新的EC
            为本次函数调用创建专门的活动对象(AO)
            在AO中创建所有函数定义中规定的局部变量
            其实AO就是函数作用域对象
                 所有局部变量都是AO的成员
            新的EC引用活动对象AO
            AO的parent指向window
            变量的使用顺序:
               先用AO(函数作用域)中的局部变量
               如果AO中没有,才去window(全局作用域)中找
        5. 函数调用后:
            本次函数调用的EC出栈
                导致函数作用域对象AO释放
                       导致局部变量一同释放


 

 

作用域链(scope chain): 由多个作用域对象连续引用形成的链式结构。掌管着一切变量的使用顺序
      顺序: 先函数作用域对象AO->延作用链向父级作用域找
      所有的变量都保存在作用域链上的对象中
          局部变量都保存在函数作用域对象AO中
          全局变量都保存在全局作用域对象window中
      控制了: 变量的使用顺序
        先用AO(函数作用域)中的局部变量
               如果AO中没有,才去window(全局作用域)中找

   3.闭包:
     什么是: 即重用变量,又防止变量被污染的一种机制
     为什么: 全局变量: 优: 可重用     缺: 易被全局污染
                 局部变量: 优: 不会被污染    缺: 不可重用
     何时: 既重用变量,又防止变量被污染
     如何: 3步:
        1. 用外层函数包裹住受保护的变量和操作变量的内层函数
        2. 外层函数将内层函数返回到外部,被外部的变量保存
        3. 通过外部变量调用内层函数,访问受保护的变量
     缺: 1. 占用更多内存: 外层函数的AO
          2. 容易造成内存泄漏
     三特点: 1. 函数嵌套:
                  2. 外层函数包含一个受保护的局部变量
                 3. 外层函数将内层函数对象返回

有几个闭包就看有几个受保护的变量

闭包如何形成:外层函数的作用域对象(AO)无法释放,即此中outer的AO无法释放

笔试:

          1、先找受保护的变量,判断外层函数执行后变量的结果

          2、再找操作变量的内层函数:

                      1、被外层函数return到外部的

                      2、也可通过直接给全局变量赋值一个函数的方式

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值