• ECMAScript6 入门 函数的扩展


    为函数参数设定默认值

    function log(x, y = 'World') {
      console.log(x, y);
    }
    
    log('Hello') // Hello World
    log('Hello', 'China') // Hello China
    log('Hello', '') // Hello
    
    注意:参数变量是默认声明的,所以不能用let或const再次声明
    使用参数默认值时,函数不能有同名参数
    // 不报错
    function foo(x, x, y) {
      // ...
    }
    
    // 报错
    function foo(x, x, y = 1) {
      // ...
    }
    // SyntaxError: Duplicate parameter name not allowed in this context
    
    参数默认值不是传值的,而是每次都重新计算默认值表达式的值。
    也就是说,参数默认值是惰性求值的(可以与vue框架计算属性进行联想理解)
    let x
    = 99; function foo(p = x + 1) { console.log(p); } foo() // 100
    //参数P的默认值是x+1,每次调用函数foo,都会重新计算x+1 x = 100; foo() // 101

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

    // 写法一
    //参数设置了默认值,但是解构对象设置了默认值
    function m1({x = 0, y = 0} = {}) {
      return [x, y];
    }
    
    // 写法二
    //参数设置了默认值,但是解构对象本身没有设置默认值
    function m2({x, y} = { x: 0, y: 0 }) {
      return [x, y];
    }
    

      

    参数默认值的位置:最好将带默认值的参数设为函数的最后面,如果不是在最后面,是不能省略的

    // 例一
    function f(x = 1, y) {
      return [x, y];
    }
    
    f() // [1, undefined]
    f(2) // [2, undefined])
    f(, 1) // 报错
    f(undefined, 1) // [1, 1]
    
    // 例二
    function f(x, y = 5, z) {
      return [x, y, z];
    }
    
    f() // [undefined, 5, undefined]
    f(1) // [1, 5, undefined]
    f(1, ,2) // 报错
    f(1, undefined, 2) // [1, 5, 2]

    参数length的属性:指定了默认值的参数,函数的length属性返回的是没有指定默认值的参数的个数,

    这是因为length属性的含义是,该函数预期传入的参数个数

    某个参数指定默认值以后,预期传入的参数个数就不包括这个参数了

    函数的length属性不包含rest参数

    作用域:一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。

    等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的

    //似乎和for循环的循环条件和循环体相同,都是不同的作用域,函数调用时,函数体内部的局部变量影响不了默认值变量
    //例子1 体现了设置默认值出现单独作用域
    var x = 1;
    
    function f(x, y = x) {
      console.log(y);//y在作用域范围内寻找x,找到了值2,就不会在寻找
    }
    
    f(2) // 2
    
    //例子2 体现了作用域链
    let x = 1;
    
    function f(y = x) {
      let x = 2;//y在作用域找,x本身没有定义,所以沿着作用域去上层找
      console.log(y);
    }
    
    f() // 1
    
    //例子3  
    function f(y = x) {
      let x = 2;
      console.log(y);   //两个不同的作用域,所以会报错
    }
    
    f() // ReferenceError: x is not defined
    
    //例子4  如果x是一个函数,也遵循着同样的道理
    var x = 1;
    
    function foo(x = x) {
      // ... //参数x = x形成一个单独作用域。实际执行的是let x = x 暂时性死区,在声明之前使用变量
    }
    
    foo() // ReferenceError: x is not defined
    var x = 1;
    function foo(x, y = function() { x = 2; }) {  //此时x变量的值都是1
      var x = 3;  //这个变量x与上面那个变量x不再同一个作用域,所以他们不是同一个变量
      y();    //执行y()以后,foo函数体内的变量x不会改变,改变的只有foo参数部分的变量
      console.log(x);   //如果去除var = 3,那么打印的值就是2.因为匿名函数里面的x与第一个参数的x是同一个作用域,所以是同一个变量
    }
    
    foo() // 3
    x // 1
     

    rest参数

    //rest 参数(形式为...变量名),将多余的参数组合成一个数组,rest是一个真正的数组
    //tip arguments是个类数组转换: Array.prototype.slice.call(arguments).sort();
    rest参数后面不允许在出现其他的参数

      function A(num,...rest){
        console.log(rest)
      }
      A(1,2,3) rest = [2,3]

    function add(...values) {
      let sum = 0;
        console.log(values.length)
    //for (var val of values) {
    //  sum += val;
    //}
    //
    //return sum;
    }
    
    add(2, 5, 3) 

    name属性:返回函数的名称如果将一个匿名函数赋值给一个变量,ES5 的name属性,

    会返回空字符串,而 ES6 的name属性会返回实际的函数名

    箭头函数

    var f = v => v;
    
    // 等同于
    var f = function (v) {
      return v;
    };
    
    1:箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分
    var f = () => 5;
    // 等同于
    var f = function () { return 5 };
    
    var sum = (num1, num2) => num1 + num2;
    // 等同于
    var sum = function(num1, num2) {
      return num1 + num2;
    };
    
    2:如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回
    var sum = (num1, num2) => { return num1 + num2; }
    
    3:如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错  会将{}里面当做一个代码块去执行,所以报错
    // 报错
    let getTempItem = id => { id: id, name: "Temp" };
    
    // 不报错
    let getTempItem = id => ({ id: id, name: "Temp" });
    
    4:箭头函数只有一行语句,且不需要返回值
    let fn = () => void doesNotReturn();
    
    注意点:
    1:函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
    2:不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
    3:可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
    4:不可以使用yield命令,因此箭头函数不能用作 Generator 函数

    5:尾部调用指的是函数最后一步是return 一个执行函数
    不忘初心,不负梦想
  • 相关阅读:
    MyBatis Generator 的使用
    Eclipse插件手动安装
    MyBatis中别名的设置
    MyBatis 插入时返回自增主键
    MyBatis 模糊查询
    MyBatis 多个查询条件的传递
    MyBatis 的Mapper中有小于号的处理
    spring mvc rest 方式
    jackson
    中兴阅读:你的移动阅读解决专家,助纸媒们一臂之力
  • 原文地址:https://www.cnblogs.com/panrui1994/p/9203051.html
Copyright © 2020-2023  润新知