ES6新语法之---函数扩展(7)

这节学习ES6中对函数新增的方法和属性。

1.新增函数的参数默认值

参考S6系列第二篇:http://www.cnblogs.com/diweikang/p/8976854.html

2.新增了函数的rest参数

参考ES6系列第二篇:http://www.cnblogs.com/diweikang/p/8976854.html

3.length属性

  作用:获取函数预期传入的参数个数。

  指定默认值后,length属性将返回没有指定默认值参数的个数。

    (function (a) {}).length // 1
    (function (a = 5) {}).length // 0
    (function (a, b, c = 5) {}).length // 2

  注意:如果设置了默认值的参数不是尾参数,length属性也不再计入后面的参数。

    (function (a = 0, b, c) {}).length // 0
    (function (a, b = 1, c) {}).length // 1

4.严格模式

  严格模式是ES5中新增语法的,限制指定的代码在更严格的模式下执行。通常在脚本开头或函数头部添加"use strict"表达式来声明。

  <1>ES5开始,函数内部可以显示声明严格模式。

    function doSomething(a, b) {
      'use strict';
      // ...
    }

  ES2016中规定,只要函数中使用了参数默认值、解构赋值、或者扩展运算符,函数内部就不允许显示声明严格模式,否则报错。

    // 参数默认值
    function doSomething(a, b = a) {
         'use strict';
          // code
    }

    // 解构赋值
    const doSomething = function ({a, b}) {
      'use strict';
      // code
    };

    // 扩展运算符
    const doSomething = (...a) => {
      'use strict';
      // code
    };

    const obj = {
      // 解构赋值
      doSomething({a, b}) {
        'use strict';
        // code
      }
    };

  规定原因:函数内部声明的严格模式,限制函数参数和函数体都必须是严格模式执行。只有执行函数体的时候才能知道函数是否是严格模式,但是函数时先执行函数参数,再执行函数体的。这就导致参数如果不遵守严格模式,函数体中又显示声明严格模式,函数进行就会报错。

    // 严格模式八进制使用0o前缀表示
    function doSomething(value = 070) {
      'use strict';
      return value;
    }

  上面函数执行就会报错。

  如何规避这种限制:

    <1>、设定全局性的严格模式。

    'use strict';

    function doSomething(a, b = a) {
      // ...
    }

    <2>、把函数包装在一个无参数的立即执行函数里面。

    const doSomething = (function () {
      'use strict';
      return function(value = 42) {
        return value;
      };
    }());

5.name属性

  ES6新增函数的name属性,返回该函数的函数名。

  <1>将一个匿名函数赋值给一个变量,ES5的name属性会返回空字符创,ES6的name属性会返回实际的函数名称。

    var f = function () {};
    // ES5
    f.name // ""
    // ES6
    f.name // "f"

  <2>将一个具名函数赋值给一个变量,ES5和ES6的name属性都会返回这个具名函数的名称。

    const bar = function baz() {};
    // ES5
    bar.name // "baz"
    // ES6
    bar.name // "baz"

  <3>构造函数返回的函数实例,name属性值为anonymous

    (new Function).name // "anonymous"

  <4>将bind返回的函数,name属性值会加上bound前缀。

    function foo() {};
    foo.bind({}).name // "bound foo"

    (function(){}).bind({}).name // "bound "

6.箭头函数

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

  <1>箭头函数需要一个参数

    var f = v => v;

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

  <2>箭头函数不需要或者需要多个参数,使用括号将参数部分括起来。

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

    var sum = (num1, num2) => num1 + num2;
    // 等同于
    var sum = function(num1, num2) {
      return num1 + num2;
    };

  <3>箭头函数代码块多余一条语句,就要使用大括号括起来,并使用return语句返回。

    var sum = (num1, num2) => { return num1 + num2; }

  <4>如果箭头函数需要返回一个对象对象外面需要小括号括起来,否则会被当成代码块返回。

    // 报错
    let getTempItem = id => { id: id, name: "Temp" };

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

  <5>如果箭头函数只有一行语句,且不需要返回值,可以采用下面的写法。

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

  <6>箭头函数与变量解构结合使用。

    const full = ({ first, last }) => first + ' ' + last;

    // 等同于
    function full(person) {
      return person.first + ' ' + person.last;
    }

  <7>箭头函数与变量解构结合使用。

    const numbers = (...nums) => nums;

    numbers(1, 2, 3, 4, 5)
    // [1,2,3,4,5]

    const headAndTail = (head, ...tail) => [head, tail];

    headAndTail(1, 2, 3, 4, 5)
    // [1,[2,3,4,5]]

  注意:箭头函数没有自身的this对象。

    1.函数体中this对象,定义时所在的对象,不是函数调用时所在对象。

    2.不可以当构造函数,也就是不可以使用new命令。

    3.不可以使用arguments对象,该对象在箭头函数体内不存在。

  <8>箭头函数中的this对象

    function foo() {
      setTimeout(() => {
        console.log('id:', this.id);
      }, 100);
    }

    var id = 21;

    foo.call({ id: 42 });
    // id: 42

  上面代码中,setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到 100 毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以输出的是42

猜你喜欢

转载自www.cnblogs.com/diweikang/p/9388321.html