函数

作者: 数据研究bot | 来源:发表于2018-10-11 00:23 被阅读6次

    函数


    基本概念

    • 函数的概念:函数就是把完成特定功能的一段代码抽取出来,使之成为程序中的一个独立实体,起个名字(函数名)。可以再同一个程序或其他程序中多次重复使用。(通过函数名调用)
    • 函数的功能:可以封装任意多条语句,而且可以在任何时候调用执行。(封装函数时,函数名=标识符,要体现出函数的功能)
    • 函数的作用:使程序变得简短清晰;有利于程序的维护;提高开发效率;提高代码的重用性。
    • 函数的分类:
    1. 内置函数(系统函数、官方函数)如:alert( ) parseInt( );
    2. 自定义函数(用户更具实际需求,自己封装一个函数。
      形参:把函数中不确定的值当做形参(形式上的参数)进行声明。
    • 声明函数
      function 函数名 ( ){
      函数体;
      }
      调用函数
      函数名();
    • 函数体内,外面怎么写JS代码,里面就怎么写。
    1. 执行程序时,程序被CPU所执行。
    2. 函数的声明,就相当于写说明书。
    3. 函数调用的时候,相当于告诉CPU,请翻到某页进行执行。
    • 有参函数:
      function 函数名(n){
      函数体;
      }
      函数名(10);
      调用时,实参要给形参进行赋值(n为形参,10为实参)
    • arguments的使用(实参列表):
      计算传入参数的和,具体传入多少参数不确定时,使用arguments。
    • 在每个函数内,都有一个内置的数组,是一个变量,叫做arguments,可存储当前函数传入的所用参数,而且通过传参的顺序进行排列的。
      arguments.length 输入传入参数的个数。
      访问arguments里面的数据,需要通过对应的下标进行访问。arguments[i];
      下标可以配合进行循环使用。



    函数声明和函数表达式声明的区别

    先上一组正常的代码


    如果同时把console.log()移到顶端,第一个函数得到的结果不变,而第二个则会报错。
    由于JS解析语句时,会把当前作用域的函数声明提前到整个作用域的最前面,而函数表达式不能提前,系统无法找到result函数,自然无法输出结果。

    匿名函数

    回调函数

    如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,则称为回调函数。(多用于递归,比如经典的斐波那契数列)



    作用域

    • 块级作用域:任何一对花括号中的语句都属于一个块,在这中定义的所有变量在代码块 外都是不可见的(JS中,只有函数有块级作用域的概念)
    • 全局变量:在函数外声明的变量是全局变量,均可访问到。
    • 局部变量:在函数内部使用var声明的变量,只能在函数内部访问,变量的作用域是局部的。

      从上面代码中可以看出,局部作用域内可以访问到全局变量,但是外部作用域无法访问局部变量。所谓的局部变量,在JS中指的仅是函数花括号内声明的变量,而其他数据类型则没有块级作用域的概念。
      注意:
    1. 不使用var声明的变量是全局变量,不推荐使用。
    2. 局部变量退出作用域之后就会被销毁,全局变量退出网页或浏览器后才被销毁。

    可以在不同的函数中使用名称相同的局部变量,因为只有声明过该变量的函数才能识别出该变量。
    只要函数运行完毕,本地变量就会被删除。


    作用域链

    [scope]:每个函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供javascript引擎存取,[[scope]]就是其中一个。[[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集合。

    作用域链:[scope]中储存了呈链式结构的执行期上下文的集合,称其为作用域链。我们可以沿着作用域顶端依次向下查找变量。
    执行期上下文:在函数执行前的那一刻,系统会创建执行期上下文的对象,当函数执行完毕,该执行期上下文被销毁。

    举个例子表示下执行过程。
    具体过程为:

    当函数执行前,函数会产生一个自己的执行期上下文,该执行期上下文会放到自己函数作用域的顶端,数字表示作用域链的顺序,函数可以沿着作用域链从顶端到下依次查找。


    变量提升

    1、

    解析:当局部内有相应的变量时,系统会在局部作用域内进行解析,如果局部内没有对应的变量,系统会沿着作用域链进行寻找。
    此段代码中变量a虽然在全局内有声明,但是函数内部也有声明,因此优先执行函数内部的。
    执行时系统自动将var a;提前,因此a的输出值为undefined。
    2、


    解析:函数声明的整体都会提前,因此优先输出,里面的变量b,c属于全局变量,而a属于局部变量,因此在全局中无法输出,会报错。

    js执行三步曲

    • 语法步骤:先通篇扫描,但不执行
    • 预编译:函数声明整体提升;变量声明部分提升(优先执行)
    • 解释执行
      局部预编译的四部曲(预编译发生在函数执行前一刻)
    1. 创建AO对象(执行期上下文)
      var a=123;===>window.a=123;
    2. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
    3. 将实参值和形参统一
    4. 在函数体里面找函数声明,值赋予函数体。
    全局预编译的三部曲
    1. 生成GO对象(window)
    2. 找形参和变量声明,将变量和形参名作为GO属性名,值为undefined
    3. 在函数体里面找函数声明,值赋予函数体。
      任何全局变量都归window所有。
      未经声明的变量,都在GO中进行预编译。
    • imply global 暗示全局变量:任何变量,如果未经声明就赋值,此变量就为全局对象(window)所有。
      a = 10; ===> windows.a = 10;
    • 一切声明的全局变量,全是window的属性。
      var a = 123; ===> window.a = 123;

    相关文章

      网友评论

          本文标题:函数

          本文链接:https://www.haomeiwen.com/subject/xelpaftx.html