第三章 函数

112 阅读2分钟

参数默认值

格式:

 function sum(a = 1, b = 2){ 
     return a + b;
 }

当调用函数时,没有传入对应参数,或传入的参数为undefined,则会自动使用默认值

 sum();                          // 3
 sum(undefined, undefined);      // 3
 sum(null, null);                // 0

细节:

  • 一个函数如果它的任意一个形参具有参数默认值,则该函数的arguments的值一旦确定,将不再与形参之间存在映射关系

     function test(a = 1, b){
         arguments[1] = 10;
         console.log(b);     // 2
     }
     ​
     test(undefined, 2);
    
  • 形参和使用let或const声明的变量一样,具有暂时性死区,不能在其被“声明”之前访问它

    各个形参被“声明”的先后顺序与形参所在位置的先后顺序有关

     function test(a = b, b){ }
     ​
     test(undefined, 1);     // Cannot access 'b' before initialization
    

剩余参数

剩余参数用于收集末尾部分的参数,将它们放置到数组中

格式:

 function test(...args){
     console.log(args);
 }
 ​
 test(1, 2, 3, 4);

注意:剩余参数必须是最后一个形参,因此一个函数也最多只能出现剩余参数

展开运算符

格式:

 var nums1 = [1, 2, 3, 4];
 ​
 var nums2 = [...nums1];     // [1, 2, 3, 4]

注意:...出现在形参部分时,表示收集剩余参数,出现在其他位置表示展开运算符

展开运算符除了可以展开数组,还能够展开对象:

 var obj1 = {
     name: "1",
     age: 2,
     sex: "男"
 };
 ​
 var obj2 = {
     ...obj1
 };
 ​
 /**
 等效于:
     var obj2 = {
         name: obj1.name,
         age: obj1.age,
         sex: obj1.sex
     };
 */

应用

函数科里化:

 function curry(fn, ...args) {
     if (args.length >= fn.length) {
         return fn.apply(this, args);
     } else {
         var that = this;
         return function (...subArgs) {
             var totalArgs = [...args, ...subArgs];
             if (totalArgs.length >= fn.length) {
                 return fn.apply(this, totalArgs);
             } else {
                 return curry.apply(that, [fn, ...totalArgs]);
             }
         }
     }
 }

箭头函数

箭头函数是一个函数表达式

格式:

(参数1, 参数2, ...) => {}

如果箭头函数的形参只有一个,则可以简化为:

参数 => {}

如果箭头函数中只有一条返回语句,则可以简化为:

() => 返回值

// 等效于:(参数) => {return 返回值}

在这种情况下,如果你要返回的内容是一个对象,则需要给返回的对象加上括号

() => ({})

细节

  1. 箭头函数中没有this

    因此不管使用什么方式调用箭头函数,其内部使用的this都是外层环境的this

  2. 箭头函数中没有arguments

  3. 箭头函数中没有new.target

  4. 箭头函数没有prototype

    但箭头函数有__proto__,并且箭头函数的__proto__为Function.prototype

  5. 箭头函数不能作为构造函数使用

    即箭头函数不能使用new关键字进行调用

扩展

除了class语法定义的类外,其它任何函数要想成为构造函数,它就不能缺少function关键字

var obj = {
    test1: function () {
        console.log(this);
    },
    test2: () => {
        console.log(this);
    },
    test3() {
        console.log(this);
    }
};

obj.test1();				// obj
obj.test2();				// window
obj.test3();				// obj
new obj.test1();			// 可以作为构造器
new obj.test2();			// 不能作为构造器
new obj.test3();			// 不能作为构造器