JavaScript函数I

函数(function)

函数是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同的值。[1]

  1. 函数的声明方式

    1. 具名定义

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      function 函数名 (参数1,参数2){
          语句
          return 返回值
      }
      //例
      function print(s) {
          console.log(s);
      }
      //上述函数返回值 return undefined
      
    2. 匿名定义

      1
      2
      3
      4
      5
      6
      
      //如果将具名函数的函数名去掉,就是匿名函数
      //这种写法一般将一个匿名函数赋值给变量,这时这个匿名函数又称为函数表达式
      //例
      let print = function(s) {
          console.log(s);
      };
      
    3. 箭头函数

      1
      2
      3
      4
      5
      6
      
      let f1 = x => x+x
      let f2 = (x,y) => x+y //( )不能省略
      let f3 = (x,y) => { return x+y }//若采用这种写法,{ }与return皆不可省略
      let f4 = (x,y) => ({ name : x , age : y })
      //在JS执行中遇到{ }会优先按照代码块处理
      //直接返回对象就会出错,需要加( )处理
      
    4. 构造函数

      1
      2
      3
      4
      5
      6
      
      //所有的函数都是由Function构造出来的
      let print = new Function('s','console.log(s)')
      //等价于
      function print(s) {
          console.log(s)
      }
      

函数的要素

  1. 执行时机

    简单来说,函数的调用时机不同,结果不同。

    详细指路👉🏻《JavaScript函数II 执行时机》🥳

  2. 作用域

    每个函数都会默认创建一个作用域

    1
    2
    3
    4
    5
    6
    7
    
    //例
    function fn(){
        let a =1
    }
    console.log(a)//a不存在
    //即使fn执行,也访问不到作用域中的a
    //let的作用域仅包含在离它最近的{ }内
    
    • 如果多个作用域都有同名变量a

      1. 查找a的声明时,依照就近原则寻找作用域
      2. 查找a的过程与函数执行无关,但a的取值与函数执行有关
    • 全局变量与局部变量

      1. 在顶级作用域声明的变量是全局变量
      2. window的属性是全局变量 其他都是局部变量
  3. 闭包

    简单来说,如果一个函数用到了函数外的变量,那么这个函数+变量就组成了闭包。

    详细指路👉🏻《关于JavaScript 作用域&闭包》🥳

  4. 形式参数

    • 形式参数即非实际参数

      1
      2
      3
      4
      5
      
      function add(x,y){
          return x+y
      }//x,y位形式参数
      
      add(1,2)//1,2是实际参数
      
    • 形式参数可认为是变量声明

      1
      2
      3
      4
      5
      6
      
      //上述代码等价于下列代码
      function add(){
          var x = arguments[0]
          var y = arguments[1]
          return x+y
      }
      
  5. 返回值

    每个函数都有返回值

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    function hi(){
        console.log('hi')
    }
    hi()
    //省略了return,返回值为undefined
    
    function hi(){
        return console.log('hi')
    }
    hi()
    //返回值为console.log('hi')的值,即undefined(hi是打印出来的值)
    

    函数执行完毕后才会返回,只有函数有返回值

  6. 调用栈

    简单来说,JS引擎在调用一个函数前,需要把函数所在的环境压进一个数组中,这个数组就叫做调用栈。

    等到函数执行完毕,就会把压进栈中的环境弹出来,返回至之前的环境,继续执行后续代码。

  7. 函数提升

    在JavaScript中,函数是“一等公民”。

    JavaScript 引擎将函数名视同变量名,所以采用function命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。[2]

  8. arguments & this

    简单来说,

    • arguments
      • 即调用函数时所传入的实际参数
      • arguments是包含所有参数的伪数组
    • this
      • 一般可以理解为this是“隐藏参数”,是当我们构造函数的时候,会经常需要调用的还没来得及定义的函数的名字
      • 目前可以使用fn.call(chocolate,1,2,3)来传this和arguments。其中chocolate为this,剩下的1,2,3是arguments。在这种定义上,this就是第一个参数,arguments是后面的所有参数。

    这是JavsScript较为难理解的一个概念,在后续更新中,为了防止this带来更多的“困扰”,箭头函数=>是没有this的。

    详细指路👉🏻《关于JavaScript this》🥳