• JavaScript中的Function


    一、Function

    什么是:

             用途:保存一段可重用的代码段的程序结构,再起一个名字。

             本质:内存中保存一段代码段的存储空间------对象

              为什么:只要一段代码,可能被反复使用时,都要定义在一个函数内,

              再起一个名字。今后,用函数名等于代码段。

    如何:

    1、创建函数:3种:

          1.以声明式方式创建:

               function 函数名(形参列表){

                       函数体

                        return 返回值

                  }

                形参:

                      什么是:专门接收从函数外部传入函数内数据的变量

                      为什么:有些函数执行时,需要动态获得必须的数据,才能正常执行。

                      何时:只要一个函数,必须某些数据才能正常执行时。

                      返回值:

                               什么是:一个函数的执行结果

                               为什么:外部调用者可能需要获得函数的执行结果

                                何时:只要外部调用者,需要获得函数的执行结果时。

               问题:会被声明提前(hoist)

    什么是:在程序开始执行前!程序会先将var声明的变量function声明的函数,提前到当前作用域的

    顶部集中创建。而赋值(=)留在原地。

    所以声明提前是js中广泛诟病的缺陷,打乱了程序正常的执行顺序

                          2.赋值方式创建:

                            var 函数名=function(形参列表){

                                   函数体

                                   return     返回值

                             } 

                       说明:赋值方式创建的函数,和声明方式创建的函数在使用时,是完全一样的

                       只不过,在程序开始执行前,赋值方式可避免函数被声明提前。保持了程序原有的执行顺序

                        揭示:js中其实函数也是一个普通的对象而已。函数名仅仅是一个普通的变量。函数名变量

                         通过对象地址引用着函数对象。

                    

    2.调用函数:

    var 变量=函数名(实参值列表)

    调用函数名,等于调用函数中的函数体

    实参值以赋值的方式传递给形参变量

    如果函数有返回值,则用变量接住。

    强调:如果一个函数,只是定义,而没有调用,

    其内部的代码是不执行的!即使出错!也不执行的!即使写错!也不会发现,也不报错!!

     3.用new 创建:(几乎不用)

    var fun=new Function("形参1"形参2,".....","函数体和返回值"); 

     二、重载(overload)

    什么是:多个同名函数,不同形参列表。在调用时,可根据传入实参列表的不同,

    动态选择匹配的函数执行。

    为什么:减少函数个数,减轻调用者负担1

    何时:只要一件事,可能根据传入的参数不同,执行不同的逻辑时,都要用重载!

    如何:

    问题:js不支持标准的重载写法。因为js不允许多个同名函数同时存在!

    解决:js中借助于arguments对象来实现重载

    什么是:每给函数内自带的,专门接受所有传入参数的实参值列表的类数组对象。

    函数内自带的:不用创建可直接使用。

    接受所有传入函数的实参值:即使没有定义形参变量,或形参变量个数少于传入

    的实参个数,都没关系!arguments可接住所有传入函数的实参值。这就是为什么

    js中的函数,定义了几个形参和调用传入几个实参,毫无关系。

    类数组对象:长得像数组的对象

    像数组:1.下标      2.length

    不是数组:是对象,不是数组家的孩子。

    何时:只要js中接收不确定个数的参数值,都用arguments。

    如何:

    1.无论传入多个参数,都只定义一个函数。

    2.在函数内直接访问argumens,根据arguments的不同,

    动态选择不同的逻辑执行任务。

    两步:

    1.定义函数时:

               function 函数(一个形参变量 obj){

               //先判断obj对象中包含哪些属性,不包含哪些属性。缺少的属性用默认值代替

               //函数执行过程中,都从对象里,取实参值使用!

            

    }

    但是,我们规定,将来调用时,所有实参值都要放在一个对象中传入

    2.调用函数时:

        函数名({属性1:实参值1,属性2:实参值2,...})

    优点:任意参数都可以缺少!都不会报错

     三、匿名函数

             什么是:定义函数时,不被任何变量引用的函数

             为什么:1.节约内存;2.划分临时作用域

                 何时:1.如果一个函数只用一次时

                            2.划分临时作用域

                  如何:1.回调函数:今后绝大多数回调函数都要定义为匿名函数----节约内存

                             2.匿名函数自调:定义函数后,立刻调用函数,调用后立即释放

                  问题:全局变量极易被污染!所以,今后禁止使用全局变量!

                  解决:今后所有js代码,都要包裹在匿名函数自调中

                   好处:绝对不会产生全局变量,节约内存,又不影响功能的执行。

    全局变量

    var start=new Date();
    alert(`开始加载页面内容,at:${start.toLocaleString()}`);

    回调函数

       function fun(){
                var start=new Date();
                alert(`开始加载页面内容,at:${start.toLocaleString()}`);
            }
            fun();
     

    匿名函数自调用      

       (function(){
              var start=new Date();
              alert(`开始加载页面内容,at:${start.toLocaleDateString()}`);
          })();
     

     四、作用域

    1.作用域(scope)

        什么是:

                 用途:作用域就是一个变量的可用范围

                 本质:作用域是保存变量的一个对象

         为什么:为了避免不同范围的变量间互相干扰!

             包括:js中只包括2级作用域

                      1.全局作用域:

                                 保存任何地方都可以访问到的变量的区域-----window对象

                                  在全局作用域中保存的变量称为全局变量

                                  全局变量:优点:公用,可反复使用

                                                    缺点:已被污染,浪费内存

                        2.函数作用域:

                                    保存仅在函数内才可使用的变量的区域-----

                                     函数作用域中保存的变量时局部变量

                                     局部变量:

                                           优点:仅在函数内可用,不会污染全局,

    且用完就释放,不占用内存!

                                            缺点:无法重用!

                                    js中没有块级作用域:

                                           块级作用域:if else else if  while do while for 这些程序结构的{},

     在js中都不是一级作用域!

                                            js中 if   else   else if   while   do while   for 这些程序结构的{}都不是作用域!

                                            js中:

                                                  if(){}里写的变量,出了if还能用!

                                                  for()里写的变量,出了for,就还能用

                             vs java 是三级作用域:

                                   全局作用域、函数作用域、块级作用域

                                   块级作用域:if else else if  while do while for 这些程序结构的{},

    在java中也是一级作用域,所以,java中也是一级作用域:

                                    if(){}里写的变量,出了if就不能用!

                                     for(){}里写的变量,出了for,就不能用

                                    程序和函数的执行过程:

                                               当程序开始执行时,先创建全局作用域对象window

                                               在window中,先保存所有全局变量和全局函数

                                               当定义函数时,每个函数其实都有一个“好友列表”,暂时包含两项。

    离自己最近的一项暂时是空的。离自己远一些的一项保存着指向window对象的地址。

     “好友列表”的作用是,将来调用函数时,万一缺变量,可按照好友列表的顺序,去朋友中找!

           当调用函数时,会临时创建这次调用函数的函数作用域对象。并在函数作用域对象中添加函数的局部变量。并将函数作用域对象的引用加入函数

    的好友列表中最近的一项中保存!说明函数和临时创建的函数作用域对象,关系最好!缺变量,先找

    临时创建的函数作用域对象。如果函数作用域对象没有,才被迫找window要。

            当函数调用后,临时创建的函数作用域对象被释放,函数作用域对象中的局部变量同时释放!

    --这就是为什么局部变量不可重用的原因!          

    五、作用域链:(Scopes)

              其实"好友列表",就是一个函数的作用域链

              什么是:一个函数可用的所有作用域对象的集合。

               普通函数的作用域链,在调用时是两个成员:

                      1.离自己最近的是临时创建的函数作用域对象

                       2.离自己稍微远一些的是全局作用域对象window

               一个函数的作用域链:

                         1.保存着这个函数可用的所有变量

                          2.控制着变量的使用顺序:

                           先局部,后全局           

    六、闭包(closure)

    什么是闭包:

            用途:即重用一个变量,又保护变量不被污染的一种编程方法。

             本质:外层函数的作用域对象,被内层函数对象引用着,无法释放。

    这个外层函数的作用域就是闭包。

            为什么:全局变量和局部变量都有不可兼得的优缺点:

                    全局变量:优:可重用        缺点:易被污染

                    局部变量:优:不会被污染  缺点:不可重用

             何时:今后,只要为一个变量保存一个专属的,可重用的,还不会被外部污染的变量。

             如何:3步:

                        1.外层函数包裹要保护的变量和内层函数

                          内层函数一定要使用了外层函数的局部变量

                         2.外层函数将内层函数抛出到外部

                         3.调用者调用外层函数,获得返回的内层函数对象,保存在变量中。并反复使用。

                闭包是如何形成的:外层函数的作用域对象,被内层函数对象引用着,无法释放。

                闭包的缺点:1.比普通函数占用更多的内存,多占用父母的函数作用域对象

                                     2.闭包不会自动释放,可能造成内存泄漏。

                 解决:使用完闭包后,如果不再使用了,要手动释放闭包。

                            闭包:pay=null;

                                        

    单词列表:

    1.overload   重载

    2.argument  参数

    3.scope   范围

    4.closure  封闭

  • 相关阅读:
    Eclipse配置SVN的几种方法及使用详情
    python爬虫实战:基础爬虫(使用BeautifulSoup4等)
    MySQL中case when的基本用法总结
    SQL常见的一些面试题(太有用啦)
    Python应用——自定义排序全套方案
    Hadoop运维
    图形化查看maven的dependency依赖
    mac os x 10.10.3 安装protoc
    创业方向:O2O及移动社交 from 沈博阳
    手动编译安装docker环境,以及偶尔出现的bug
  • 原文地址:https://www.cnblogs.com/sna-ling/p/11869558.html
Copyright © 2020-2023  润新知