• 7.函数的拓展


    函数的扩展

    一.函数参数的默认值

    1. 基本用法

    1. ES6之前,不能直接为函数的参数设置默认值,只能在函数体内进行判断并给它赋默认值

      //判断y是否存在,不存在则给它默认值 'world'
      function func(x,y){
          y ? y : 'world';
          console.log(x + y);
      }
      
    2. ES6允许为函数的参数设置默认值,即直接写在参数定义的后面**

      • 注意:
      • 函数的参数是默认声明的,不能使用 let 和 const 再次声明
      • 参数默认值是惰性求值,只有当需要用到的时候,才会重新计算
      function func(x,y = 'world'){
          console.log(x + y);
      }
      func('hello');			//helloworld
      func("hello","");		//hello
      

    2.与解构赋值默认值结合使用

    1. 参数的默认值可以和解构赋值的默认值结合使用

    2. 思考:下面两种写法,有什么区别

      function m1({x = 0,y = 0} = {}){
          console.log(`[${x},${y}]`)
      }
      
      function m2({x,y} = {x:0,y:0}){
          console.log(`[${x},${y}]`)
      }
      
      • 第一种写法,函数参数的默认值是空对象,但是,设置了对象解构的默认值
      • 第二种写法,设置了函数参数的默认值,但是没有设置对象解构的默认值
      m1();				//[0,0]
      m2();				//[0,0]
      
      m1({x:3});			//[3,0]
      m2({x:3});			//[3,undefined]
      
      m1({x:3,y:5});		//[3,5]
      m2({x:3,y;5});		//[3,5]
      
      m1({});				//[0,0]
      m2({});				//[undefined,undefined]
      

    3.参数默认值的位置

    1. 看如下示例

      function func(x=0,y){
          console.log(`[${x},${y}]`);
      }
      
      func();					//[0,undefined]
      func(1);				//[1,undefined]
      func(,3);				//报错
      func(undefined,3);		//[0,3]
      
    2. 第二个示例

      function func(x,y=0,z){
          console.log(`[${x},${y},${z}]`)
      }
      
      func();					//[undefined,0,undefined]
      func(1)					//[1,0,undefined]
      func(1,,2)				//报错
      func(1,undefined,2)		//[1,0,2]
      
    3. 总结如上两个示例,可以发现

      • 如果非尾部的参数设置默认值,实际上这个参数是没办法省略的,至少得指定undefined,否则报错
      • 当默认参数在最后的位置的时候,可不用指定
    4. 综上所述,拥有默认值的参数,一般放在参数列表的最后面

    4.函数的length属性

    1. 指定了参数默认值的情况下,函数的length属性将只返回没有没有默认值的参数个数

      (function func(x,y){}).length;			//2
      (function func(x=0,y){}).length;		//1
      

    5.默认参数的作用域

    1. 一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域,等到初始化结束,作用域就会消失。这种语法行为,在不设置参数默认值的时候,是不会出现的

      • 如下示例:
      var x = 1;
      function foo(x,y=function(){x=2;}){
          var x = 3;
          y();
          console.log(x);
      }
      foo();					//3
      console.log(x);			//1
      
      • 示例解析:在以上示例中,函数的参数形成了一个单独的作用域,在作用域内部,声明了一个变量x,声明了变量y,y的默认值为一个函数,这个函数内部的x指向同一个作用域的第一个参数x。在函数内部,又声明了一个x,该变量与参数内部的x不是同一个作用域,所以不是同一个变量,因此执行y后,函数内部的x变量和函数外部的x变量都没有发生变化
      • 如果去掉函数内部的 var 声明,则函数内部的x变量和函数的第一个参数x是同一个变量,所以执行完y()方法之后,内部的x返回2
      var x = 1;
      function foo(x,y=function(){x=2;}){
          x = 3;
          y();
          console.log(x);
      }
      foo();					//2
      console.log(x);			//1
      

    6. 应用

    • 可以将函数的某些参数的默认值设置为一个抛出异常的函数,当这些参数为undefined的时候,就会抛出异常
    • 将参数的默认值设置为undefined,说明该参数可以被忽略

    二.rest参数

    1. ES6引入了rest参数,形式为(...变量名)。用户获取函数的多余参数,这样就不需要使用arguments对象了

      • 注意:rest之后不能有其它参数,否则会报错
      • rest参数就是一个数组,就函数多余的参数放入数组中
      • 函数的length属性,不包含rest参数
      function func(...numbers){
          console.log(numbers);
      }
      func(1,2,3);		//[1,2,3]
      console.log(func.length)		//0
      

    三.严格模式

    1. 从ES5开始,函数内部可以设置严格模式

      function func(){
          'user strict';
          //code...
      }
      
    2. ES6做了一点修改,规定只要函数参数使用了默认值,解构赋值,或者扩展运算符,那么函数内部就不能设定为严格模式,否则会报错

      function func(x=10){
          'use strict'
          //...报错
      }
      

    四.name属性

    1. 函数的name属性,返回该函数的函数名,这个属性很早就被浏览器支持,但是在ES6中,才将其写入标准

      • 注意:
      • 如果将一个匿名函数赋值给一个变量,ES5的name属性将会返回一个空串,在ES6中,会返回被赋值的变量名
      • 如果将一个拥有名字的函数赋值给一个变量,不论是ES5还是ES6,其name属性会返回该函数原来的名字
      const f = function bar(){}
      f.name;		// bar
      
      • Function 构造函数返回的实例,name属性值为 anonymous
      (new Function).name			//annoymous
      

    五.箭头函数

    1. 基本用法

    • ES6允许使用“箭头”(=>)定义函数
    var f = v => v;
    
    //等同于
    var f = function(v){
        return v;
    }
    
    • 如果箭头函数不需要参数或者需要多个参数,就可以 使用一个圆括号代表参数部分
    var f = () => 5
    //等价于
    var f = function(){
        return 5;
    }
    
    var f = (x,y) => x + y
    //等价于
    var f = function(x,y){
        return x + y;
    }
    
    • 如果箭头函数直接返回一个对象,必须在对象外面加上圆括号,否则会报错
    //报错
    let getTempItem = id => {id:id,name:'temp'}
    
    //不报错
    let getTempItem = id => ({id:id,name:'temp'})
    
    
    • 箭头函数可以和变量解构结合使用
    let func = {first,lasst} => first + ',' + last
    
    //等价于
    function func({first,lasst}){
        return person.last + "," + person.last;
    }
    
    
    • 箭头函数可以简化回调函数
    • 箭头函数可以和rest参数一起使用

    2. 使用注意点

    1. 函数内的this对象,就是定义时所在的对象,而不是使用时所在的对象

    2. 不可以当做构造函数,也就是说不可以使用new进行实例化,否则报错

    3. 不可以使用arguments对象,但是可以使用rest参数代替

    4. 不可以使用yield命令,因此箭头函数不能用作Generator函数

    5. 箭头函数中的this,详细说明

      • 箭头函数没有自己的this,所以箭头函数的this总是指向定义该箭头函数的那个对象
      • 箭头函数让this的指向固定化
      • 除了this,以下变量在箭头函数中也是不存在的,arguments,super,new.target

      示例说明

      var handle = {
          id:'123456',
          init:function(){
              document.addEventListener('click',event => this.doSomeThing(event.type),false)
          },
          doSomeThing:function(type){
              console.log('Handing' + type + 'for' + this.id)
          }
      };
      
      

      示例解析:

      • 上面代码中的init函数中使用了箭头函数,这导致箭头函数里面的this,永远指向handler对象,否则,使用this.doSomeThing调用的时候,就会报错

    3. 不适用场合

    1. 由于箭头函数把this由动态变为静态,所以在以下场合,不应该使用箭头函数
      • 定义对象的方法
      • 需要动态this的时候

    六.尾调用优化

    1. 什么是尾调用

    • 在某个函数的最后一步是调用另一个函数
    function f(x){
        return g(x);
    }
    
    
    • 没有按照上例中返回函数调用的,都不算尾调用
    //非尾调用示例
    function f(x){
        let y = g(x);
        return y;
    }
    
    function f(x){
        return g(x) + 1;
    }
    
    function f(x){
        g(x);
    }
    
    

    七.函数参数的尾逗号

    1. ES2017允许函数的最后一个参数可以有逗号,此前,这个都是不被允许的

    总结

    1. ES6中,可以为函数添加默认值,默认值可以和解构赋值一起使用
      • 函数默认值的位置最好放在函数参数的最后面,否则还是要在参数中使用undefined来使用默认参数,这使得默认参数没有什么意义
      • 使用默认参数的函数,length返回只会返回没有默认值参数的个数
      • 一旦设置了函数的默认参数,参数会形成一个单独的作用域
    2. ES6中新增了rest参数,rest参数可以接受所有未在函数参数列表中声明的参数,还可以代替arguments对象
    3. 使用了参数默认值,解构赋值和扩展运算符的函数,内部都不能指定严格模式,否则报错
    4. 函数的name属性可以返回函数名,将具名函数赋值给变量之后,name属性获取的还是函数的原始名
    5. 箭头函数可以简化函数的书写,但是得注意,箭头函数的this永远指向定义它的外城对象,箭头函数将动态的this变为了固定的
  • 相关阅读:
    PAT——1069. 微博转发抽奖
    PAT——1068. 万绿丛中一点红
    PAT——1066. 图像过滤
    PAT——1065. 单身狗
    PAT——1064. 朋友数
    PAT——1063. 计算谱半径
    PAT——1062. 最简分数
    PAT——1061. 判断题
    PAT——1060. 爱丁顿数
    PAT——1059. C语言竞赛
  • 原文地址:https://www.cnblogs.com/mapengfei247/p/11105062.html
Copyright © 2020-2023  润新知