JavaScript箭头函数

  1. 箭头函数表达式比一般函数表达式更加简洁,但是在语法上是有一定区别
  2. 箭头函数没有独立的'this',arguments和super绑定,且不可以被用作方法
  3. 箭头函数不可以用作构造函数,使用new调用会引发TypeError报错。并且无法访问new.target关键字。
  4. 箭头函数不能在主体中使用yield,也不能作为生成器函数创建。
  5. const mater = ['jik','mik','kun','kim','lux']
    console.log(mater.map((mater) = > mater.length));
    //outlook":Array [8, 6, 7, 9]
  6. () => expression
    
    param => expression
    
    (param) => expression
    
    (param1, paramN) => expression
    
    //箭头函数表达式  第一种 
    
    () => {
      statements
    }
    
    param => {
      statements
    }
    
    (param1, paramN) => {
      statements
    }
    
    //箭头函数表达式第二种

      参数部分支持剩余参数、默认参数和解构赋值,并且始终需要使用括号:

  7. (a, b, ...r) => expression
    (a = 400, b = 20, c) => expression
    ([a, b] = [10, 20]) => expression
    ({ a, b } = { a: 10, b: 20 }) => expression
    
  8. 箭头函数可以是 async 的,方法是在表达式前加上 async 关键字。

    async param => expression
    async (param1, param2, ...paramN) => {
      statements
    }
    
  9. 概述:

    让我们逐步将传统的匿名函数分解为最简单的箭头函数。每一步都是一个有效的箭头函数。备注:传统函数表达式和箭头函数除了语法上的区别外,还有更多的不同。我们将在接下来的几个小节中详细介绍它们的行为差异
  10. 案例:参数周围的括号和函数体周围的大括号都可以省略。但是,只有在某些情况下才能省略。只有当函数只有一个简单参数时,才能省略括号。如果函数有多个参数、无参数、默认参数、重组参数或其余参数,则需要在参数列表周围加上括号。
    // 传统匿名函数
    (function (a) {
      return a + 100;
    });
    
    // 1. 移除“function”,并将箭头放置于参数和函数体起始大括号之间
    (a) => {
      return a + 100;
    };
    
    // 2. 移除代表函数体的大括号和“return”——返回值是隐含的
    (a) => a + 100;
    
    // 3. 移除参数周围的括号
    a => a + 100;
    
  11. 只有当函数直接返回表达式时,才可以省略大括号。如果函数体有额外的处理,则大括号是必需的,return 关键字也是必需的。箭头函数无法猜测函数体返回什么或何时返回。

    // 传统匿名函数
    (function (a, b) {
      return a + b + 100;
    });
    
    // 箭头函数
    (a, b) => a + b + 100;
    
    const a = 4;
    const b = 2;
    
    // 传统无参匿名函数
    (function () {
      return a + b + 100;
    });
    
    // 无参箭头函数
    () => a + b + 100;
    

       

  12. 箭头函数总是未命名的。如果箭头函数需要调用自身,请使用具名函数表达式。也可以将箭头函数赋值给一个变量,这样它就有了名字。

    // 传统匿名函数
    (function (a, b) {
      const chuck = 42;
      return a + b + chuck;
    });
    
    // 箭头函数
    (a, b) => {
      const chuck = 42;
      return a + b + chuck;
    };
    
    // 传统函数
    function bob(a) {
      return a + 100;
    }
    
    // 箭头函数
    const bob2 = (a) => a + 100;
    
  13. 函数体

    箭头函数既可以使用表达式体(expression body),也可以使用通常的块体(block body)。

    在表达式体中,只需指定一个表达式,它将成为隐式返回值。在块体中,必须使用显式的 return 语句。

    const func = (x) => x * x;
    // 表达式体语法,隐含返回值
    
    const func2 = (x, y) => {
      return x + y;
    };
    // 块体语法,需要明确返回值
    
  14. 使用表达式体语法 (params) => { object: literal } 返回对象字面量时,不能按预期工作。
    const func = () => { foo: 1 };
    // 调用 func() 会返回 undefined!
    
    const func2 = () => { foo: function () {} };
    // SyntaxError: function statement requires a name
    
    const func3 = () => { foo() {} };
    // SyntaxError: Unexpected token '{'
    

    这是因为只有当箭头后面的标记不是左括号时,JavaScript 才会将箭头函数视为表达式体,因此括号({})内的代码会被解析为一系列语句,其中 foo 是标签,而不是对象文字中的键。

    要解决这个问题,可以用括号将对象字面量包装起来:

    const func = () => ({ foo: 1 });
    
  15. 不能用作方法

    箭头函数表达式只能用于非方法函数,因为它们没有自己的 this。让我们看看将它们用作方法时会发生什么:
    "use strict";
    
    const obj = {
      i: 10,
      b: () => console.log(this.i, this),
      c() {
        console.log(this.i, this);
      },
    };
    
    obj.b(); // 输出 undefined, Window { /* … */ }(或全局对象)
    obj.c(); // 输出 10, Object { /* … */ }
    
  16. 另外一个示例涉及到 Object.defineProperty():
    "use strict";
    
    const obj = {
      a: 10,
    };
    
    Object.defineProperty(obj, "b", {
      get: () => {
        console.log(this.a, typeof this.a, this); // undefined 'undefined' Window { /* … */ }(或全局对象)
        return this.a + 10; // 代表全局对象 'Window',故 `this.a' 返回 'undefined'
      },
    });
    
  17. 由于类体具有 this 上下文,因此作为类字段的箭头函数会关闭类的 this 上下文,箭头函数体中的 this 将正确指向实例(对于静态字段来说是类本身)。但是,由于它是一个闭包,而不是函数本身的绑定,因此 this 的值不会根据执行上下文而改变。
    class C {
      a = 1;
      autoBoundMethod = () => {
        console.log(this.a);
      };
    }
    
    const c = new C();
    c.autoBoundMethod(); // 1
    const { autoBoundMethod } = c;
    autoBoundMethod(); // 1
    // 如果这是普通方法,此时应该是 undefined
    
  18. 箭头函数属性通常被称作“自动绑定方法”,因为它与普通方法的等价性相同:
    备注:类字段是在实例(instance)上定义的,而不是在原型(prototype)上定义的,因此每次创建实例都会创建一个新的函数引用并分配一个新的闭包,这可能会导致比普通非绑定方法更多的内存使用。
    出于类似原因, call()、apply()和  bind()方法在箭头函数上调用时不起作用,因为箭头函数是根据箭头函数定义的作用域来建立 this 的,而 this 值不会根据函数的调用方式而改变
    class C {
      a = 1;
      constructor() {
        this.method = this.method.bind(this);
      }
      method() {
        console.log(this.a);
      }
    }
  19.  没有参数绑定

    箭头函数没有自己的 arguments对象。因此,在本例中,arguments 是对外层作用域参数的引用:
    备注:在 严格模式下不能声明名为 arguments 的变量,因此上面的代码会出现语法错误。这使得 arguments 的范围效应更容易理解。
    function foo(n) {
      const f = () => arguments[0] + n; // foo 的隐式参数绑定。arguments[0] 为 n
      return f();
    }
    
    foo(3); // 3 + 3 = 6
    
       ​​​
  20. 在大多数情况下,使用剩余参数是比使用 arguments 对象更好的选择。
    function foo(n) {
      const f = (...args) => args[0] + n;
      return f(10);
    }
    
    foo(1); // 11
    
  21. 不能用作构造函数

    箭头函数不能用作构造函数,当使用 new调用时会出错。它们也没有 prototype属性。
    const Foo = () => {};
    const foo = new Foo(); // TypeError: Foo is not a constructor
    console.log("prototype" in Foo); // false
    
  22. 箭头前换行

    箭头函数的参数和箭头之间不能换行。

    const func = (a, b, c)
      => 1;
    // SyntaxError: Unexpected token '=>'
    

  23. 为便于格式化,可在箭头后换行,或在函数体周围使用括号/花括号,如下图所示。也可以在参数之间换行。

    const func = (a, b, c) =>
      1;
    
    const func2 = (a, b, c) => (
      1
    );
    
    const func3 = (a, b, c) => {
      return 1;
    };
    
    const func4 = (
      a,
      b,
      c,
    ) => 1;
    
  24. 函数的优先级
    箭头函数表达式-JavaScript|MDN(mozilla.org)

你可能感兴趣的:(javascript,开发语言,ecmascript)