箭头函数

一.语法

基础语法

//1. 前面圆括号,后面大括号
(param1, param2, …, paramN) => { statements; }

/* 2.当删除大括号时,它将是一个隐式的返回值,这意味着咱们不须要指定咱们返回*/
(param1, param2, …, paramN) => expression;

// 等价于 
(param1, param2, …, paramN) => { return expression; } 

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

// 等价于

singleParam => { statements; }



//4.若是箭头函数 有多参数, 必须使用 ()圆括号: 

() => { statements; } 



//5.若是箭头函数 无参数 , 必须使用 ()圆括号或者 _下划线:

() => { statements; } 
或
_ => { statements; }

二. 描述

箭头函数的引入有两个方面的做用:一是更简短的函数书写,二是对 this的词法解析。javascript

1.更短的函数

更短的函数在函数式编程里很受欢迎。试比较:java

var a = [
  "Hydrogen",
  "Helium",
  "Lithium",
  "Beryl­lium"
];

var a2 = a.map(function(s){ return s.length });

var a3 = a.map( s => s.length );
var f = v => v;
//上面的箭头函数等同于:
var f = function(v) {
  return v;
};

2.不绑定this

在箭头函数出现以前,每一个新定义的函数都有其本身的 this 值(例如,构造函数的 this 指向了一个新的对象;严格模式下的函数的 this 值为 undefined;若是函数是做为对象的方法被调用的,则其 this 指向了那个调用它的对象)。在面向对象风格的编程中,这会带来不少困扰。express

function Person() {
    // 构造函数 Person() 定义的 `this` 就是新实例对象本身
    this.age = 0;
    setInterval(function growUp() {
        // 在非严格模式下,growUp() 函数定义了其内部的 `this`为全局对象, 
        // 不一样于构造函数Person()的定义的 `this`
        this.age++;
    }, 3000);
}

var p = new Person();

在 ECMAScript 3/5 中,这个问题经过把this的值赋给变量,而后将该变量放到闭包中来解决。编程

function Person() {
    var self = this; 
    // 也有人选择使用 `that` 而非 `self`, 只要保证一致就好.
    self.age = 0;
    setInterval(function growUp() {
        // 回调里面的 `self` 变量就指向了指望的那个对象了
        self.age++;
    }, 3000);
}

var p = new Person();

除此以外,还可使用 bind 函数,把指望的 this 值传递给 growUp() 函数。segmentfault

3.箭头函数会捕获其所在上下文的  this 值

做为本身的 this 值,所以下面的代码将如期运行。闭包

function Person() {  
    this.age = 0;  
    setInterval(() => {
        // 回调里面的 `this` 变量就指向了指望的那个对象了
        this.age++;
    }, 3000);
}

var p = new Person();

 

三.向使用方法同样使用箭头函数

1.如上所述,箭头函数表达式对非方法函数是最合适的。让咱们看看当咱们试着把它们做为方法时发生了什么。函数式编程

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

箭头函数没有定义this绑定。 函数

2.另外一个涉及Object.defineProperty():的示例:ui

'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'
  }
});

3.箭头函数使用注意点 http://www.javashuo.com/article/p-gmfwqrpy-h.html

  1. 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。this

  2. 不能够看成构造函数,也就是说,不可使用new命令,不然会抛出一个错误。

  3. 不可使用arguments对象,该对象在函数体内不存在。若是要用,能够用Rest参数代替。

  4. 不可使用yield命令,所以箭头函数不能用做Generator函数。

this 指向固定化

ES5规范中,this对象的指向是可变的,可是在ES6的箭头函数中,它倒是固定的。

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。

 

四.使用new操做符

箭头函数不能用做构造器,和 new 一块儿用就会抛出错误。

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

五.使用原型属性

箭头函数没有原型属性。

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

六. 返回文字表达式

请牢记,用 params => {object:literal} 这种简单的语法返回一个文字表达式是行不通的:

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

var func = () => {  foo: function() {}  };
// SyntaxError: function statement requires a name(未定义函数语句)

这是由于花括号(即 {} )里面的代码被解析为序列语句了(例如, foo 被认为是一个标签, 而非文字表达式的组成部分)。

因此,记得用圆括号把文字表达式包起来:

var func = () => ({ foo: 1 });
相关文章
相关标签/搜索