概述

  1. 函数的声明方式:
  • function命令
  • 表达式赋值
  • 构造函数
  1. 函数的return和递归(recursion)
  • 只有函数才有返回值
  • return后面不能直接换行或者需用括号包住
  • 函数可以调用自身,即递归
  1. 函数名的提升
  • 由于函数和其他类型的值地位相同,所以也存在变量提升,可以先调用后定义

函数的属性和方法

  1. name属性:
    function f1() {}
    f1.name // "f1"
    var f2 = function () {};
    f2.name // "f2"
    var myFunc = function () {};
    function test(f) {
     console.log(f.name);
    }
    test(myFunc) // myFunc
  2. length属性
    函数定义完以后,参数的个数即确定,这种特性实现了一种设计模式---“重载”
    function f(a, b) {}
    f.length // 2
    f(1,2,1,1,1)
    f.length //2
  3. 函数的作用域
  • JavaScript有两种作用域,一种全局作用域,一种函数作用域或局部作用域,ES6新增块级作用域。
  • 函数内部可以读取它上一层作用域定义的变量,反之外部不能读取函数内部的变量。
  • 函数内部存在变量提升
    function foo(x) {
    if (x > 100) {
    var tmp = x - 100;
    }
    }
    // 等同于
    function foo(x) {
    var tmp;
    if (x > 100) {
    tmp = x - 100;
    };
    }
  • 函数本身的作用域
    它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关
    function foo() {
    var x = 1;
    function bar() {
    console.log(x);
    }
    return bar;
    }
    var x = 2;
    var f = foo();
    f() // 1

4.函数的参数

  • 函数的参数可以省略,但是不能只省略靠前的参数,必须显示的传入undefined
    function f(a, b) {
    return a;
    }
    f( , 1) // SyntaxError: Unexpected token ,(…)
    f(undefined, 1) // undefined
  • 参数的传递方式
    1.传入原始类型的值就拷贝值
    2.传入引用类型的值就拷贝地址
  • arguments对象
    1.非严格模式下,可以在函数内部对arguments对象进行读和写
    2.严格模式下,对arguments对象的值只能读,修改则不起作用
    3.arguments是伪数组,ES6可以通过Array.from()变成真正的数组