我是靠谱客的博主 甜蜜冬日,最近开发中收集的这篇文章主要介绍ES6 Arrow functions,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

一个箭头函数表达式比函数表达式更短, 且没有和它自己的 this, arguments, super, or new.target绑定。这些 函数表达式适用于r non-method函数, 且它们不能用于constructors.

SyntaxEdit

Basic Syntax

(param1, param2, …, paramN) => { statements }//固定对象表示法
(param1, param2, …, paramN) => expression
// equivalent to: (param1, param2, …, paramN) => { return expression; }

// 圆括号是可选的,下面只有一个参数:
(singleParam) => { statements }
 singleParam => { statements }

// 无参.
() => { statements }

Advanced Syntax

// Parenthesize the body of function to 返回一个对象的固定值表达式;
params => ({foo: bar})

// Rest parameters and default parameters are supported
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }

// Destructuring within the parameter list is also supported
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();  
// 6

DescriptionEdit

See also "ES6 In Depth: Arrow functions" on hacks.mozilla.org.

Two factors influenced the introduction of arrow functions: shorter functions and non-binding of this.

Shorter functions

var materials = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

materials.map(function(material) { 
  return material.length; 
}); // [8, 6, 7, 9]

materials.map((material) => {
  return material.length;
}); // [8, 6, 7, 9]

materials.map(material => material.length); // [8, 6, 7, 9]

No binding of this

Until arrow functions, every new function defined its own this value (a new object in the case of a constructor, undefined in strict mode function calls, the base object if the function is called as an "object method", etc.). This proved to be annoying with an object-oriented style of programming.

function Person() {
  // The Person() 构造函数定义了 `this` 作为自己的实例.
  this.age = 0;

  setInterval(function growUp() {
    // 在non-strict 模式, the growUp() 函数定义 `this` 
    // 和Person()构造函数定义的this不同。
    this.age++;
  }, 1000);
}

var p = new Person();

In ECMAScript 3/5, the this issue was fixable by assigning the value in this to a variable that could be closed over.

function Person() {
  var that = this;
  that.age = 0;

  setInterval(function growUp() {
    // The callback refers to the `that` variable of which
    // the value is the expected object.
    that.age++;
  }, 1000);
}

Alternatively, a bound function could be created so that a preassigned this value would be passed to the bound target function (the growUp() function in the example above).

An arrow function does not create its own this, the this value of the enclosing execution context is used. Thus, in the following code, the this within the function that is passed to setInterval has the same value as this in the enclosing function:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();
Relation with strict mode

Given that this is lexical, strict mode rules with regard to this are ignored.

var f = () => { 'use strict'; return this; };
f() === window; // or the global object

All other strict mode rules apply normally.

Invoked through call or apply

Since this is not bound in arrow functions, the methods call() or apply() can only pass in parameters. this is ignored.

var adder = {
  base: 1,

  add: function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var b = {
      base: 2
    };

    return f.call(b, a);
  }
};

console.log(adder.add(1));         // This would log to 2
console.log(adder.addThruCall(1)); // This would log to 2 still

No binding of arguments

Arrow functions do not bind an arguments object. Thus, in this example, arguments is simply a reference to the same name in the enclosing scope:

var arguments = 42;
var arr = () => arguments;

arr(); // 42

function foo() {
  var f = (i) => arguments[0] + i; // foo's implicit arguments binding
  return f(2);
}

foo(1); // 3

In most cases, using rest parameters is a good alternative to using an arguments object.

function foo() { 
  var f = (...args) => args[0]; 
  return f(2); 
}

foo(); // 2

Arrow functions used as methods

As stated previously, arrow function expressions are best suited for non-method functions. Let's see what happens when we try to use them as methods:

'use strict';
var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log(this.i, this);
  }
}
obj.b(); // prints undefined, Window {...} (or the global object)
obj.c(); // prints 10, Object {...}

Arrow functions do not define ("bind") their own this. Another example involving Object.defineProperty():

'use strict';
var obj = {
  a: 10
};

Object.defineProperty(obj, 'b', {
  get: () => {
    console.log(this.a, typeof this.a, this);
    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
  }
});

Use of the new operator

Arrow functions cannot be used as constructors and will throw an error when used with new.

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

Use of prototype property

Arrow functions do not have a prototype property.

var Foo = () => {};
console.log(Foo.prototype); // undefined

Use of the yield keyword

The yield keyword may not be used in an arrow function's body (except when permitted within functions further nested within it). As a consequence, arrow functions cannot be used as generators.

Function bodyEdit

Arrow functions can have either a "concise body" or the usual "block body".

In a concise body, only an expression is needed, and an implicit return is attached. In a block body, you must use an explicit return statement.

var func = x => x * x;                  
// concise syntax, implied "return"

var func = (x, y) => { return x + y; }; 
// with block body, explicit "return" needed

Returning object literalsEdit

Keep in mind that returning object literals using the concise syntax params => {object:literal} will not work as expected.

var func = () => { foo: 1 };               
// Calling func() returns undefined!

var func = () => { foo: function() {} };   
// SyntaxError: function statement requires a name

This is because the code inside braces ({}) is parsed as a sequence of statements (i.e. foo is treated like a label, not a key in an object literal).

Remember to wrap the object literal in parentheses.

var func = () => ({foo: 1});

Line breaksEdit

An arrow function cannot contain a line break between its parameters and its arrow.

var func = ()
           => 1; 
// SyntaxError: expected expression, got '=>'

Parsing orderEdit

Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with operator precedence compared to regular functions.

let callback;

callback = callback || function() {}; // ok

callback = callback || () => {};      
// SyntaxError: invalid arrow-function arguments

callback = callback || (() => {});    // ok

More examplesEdit

// An empty arrow function returns undefined
let empty = () => {};

(() => 'foobar')(); 
// Returns "foobar"
// (this is an Immediately Invoked Function Expression 
// see 'IIFE' in glossary)

var simple = a => a > 15 ? 15 : a; 
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

// Easy array filtering, mapping, ...

var arr = [5, 6, 13, 0, 1, 18, 23];

var sum = arr.reduce((a, b) => a + b);  
// 66

var even = arr.filter(v => v % 2 == 0); 
// [6, 0, 18]

var double = arr.map(v => v * 2);       
// [10, 12, 26, 0, 2, 36, 46]

// More concise promise chains
promise.then(a => {
  // ...
}).then(b => {
  // ...
});

// Parameterless arrow functions that are visually easier to parse
setTimeout( () => {
  console.log('I happen sooner');
  setTimeout( () => {
    // deeper code
    console.log('I happen later');
  }, 1);
}, 1);


最后

以上就是甜蜜冬日为你收集整理的ES6 Arrow functions的全部内容,希望文章能够帮你解决ES6 Arrow functions所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部