• ES6 函数的扩展


    一、函数参数的默认值

    1、基本用法

    ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

    function log(x, y = 'World') {
      console.log(x, y);
    }
    
    log('Hello') // Hello World
    log('Hello', 'China') // Hello China
    log('Hello', '') // Hello

     

    2、作用域

    一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。等到初始化结束,这个作用域就会消失。

    var x = 1;
    function f(x, y = x) {
      console.log(y);
    }
    
    f(2) // 2

    上面代码中,参数y的默认值等于变量x。调用函数f时,参数形成一个单独的作用域。在这个作用域里面,默认值变量x指向第一个参数x,而非全局变量x,所以输出是2

    再看下面的例子。

    let x = 1;
    function f(y = x) {
      let x = 2;
      console.log(y);
    }
    
    f() // 1

    上面代码中,函数f调用时,参数 y=x 形成一个单独的作用域。这个作用域里面,变量x本身没有定义,所以指向外层的全局变量x。函数调用时,函数体内部的局部变量x影响不到默认值变量x

    如果此时,全局变量x不存在,就会报错。

    function f(y = x) {
      let x = 2;
      console.log(y);
    }
    
    f() // ReferenceError: x is not defined

     

    二、rest 参数

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

    function test(...arg){
        for(let v of arg){
            console.log(v);
        }
    }
    test(1,2,3);
    
    输出结果:
    1
    2
    3

    下面是一个求和函数,利用 rest 参数,向 add 函数传入任意数目的参数

    function add(...values) {
      let sum = 0;
      for (var a of values) {
        sum += a;
      }
      return sum;
    }
    
    add(1, 2, 3) // 6

    下面用 rest 参数代替 arguments 变量

    // arguments变量的写法
    function sortNumbers() {
      return Array.prototype.slice.call(arguments).sort();
    }
    
    // rest参数的写法
    const sortNumbers = (...numbers) => numbers.sort();

    arguments 对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,必须使用 Array.prototype.slice.call 先将其转为数组。

    rest 参数就不存在这个问题,它就是一个真正的数组,数组特有的方法都可以使用。

     

    三、箭头函数

    1、基本用法

    ES6 允许使用“箭头”(=>)定义函数。

    var f = v => v;
    // 等同于
    var f = function (v) { return v; };

    若箭头函数不需要参数,则用一个 () 代表参数部分。

    var f = () => 5;
    // 等同于
    var f = function () { return 5 };

    由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

    // 报错
    let getTemp = id => { id: id, name: "Temp" };
    
    // 不报错
    let getTemp = id => ({ id: id, name: "Temp" });

    如果箭头函数只有一行语句,且不需要返回值,则可以省略 { }

    let fn = () => void doesNotReturn();

    下面是 rest 参数与箭头函数结合的例子。

    const numbers = (...nums) => nums;
    numbers(1, 2, 3, 4, 5)
    // [1,2,3,4,5]

    2、几个注意点

    (1)函数体内的 this 对象是定义时所在的对象,而非使用时所在的对象;

    (2)不可以当作构造函数,也就是说,不可以使用new命令,否则会报错;

    (3)不可以使用arguments对象,该对象在函数体内不存在,如果要用,可以用 rest 参数代替;

    (4)由于箭头函数没有自己的this,所以当然也就不能用call()apply()bind()这些方法去改变this的指向。

     

    3、嵌套的箭头函数

    箭头函数内部,还可以再使用箭头函数。下面是一个 ES5 语法的多重嵌套函数。

    function insert(value) {
      return {into: function (array) {
        return {after: function (afterValue) {
          array.splice(array.indexOf(afterValue) + 1, 0, value);
          return array;
        }};
      }};
    }
    
    insert(2).into([1, 3]).after(1); //[1, 2, 3]

    上面这个函数,可以使用箭头函数改写。

    let insert = (value) => ({into: (array) => ({after: (afterValue) => {
      array.splice(array.indexOf(afterValue) + 1, 0, value);
      return array;
    }})});
    
    insert(2).into([1, 3]).after(1); //[1, 2, 3]

     

    四、尾调用

    指某个函数的最后一步是调用另一个函数

    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);
    }
  • 相关阅读:
    模拟--北京标准时间
    DOM方法
    Document-对象属性和常用的对象方法
    struts2标签
    OGNL
    Java基础方面
    初识拦截器
    访问者模式
    备忘录模式
    门面模式
  • 原文地址:https://www.cnblogs.com/Leophen/p/11197948.html
Copyright © 2020-2023  润新知