//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
更短的函数在函数式编程里很受欢迎。试比较:java
var a = [ "Hydrogen", "Helium", "Lithium", "Beryllium" ]; 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; };
在箭头函数出现以前,每一个新定义的函数都有其本身的 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
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' } });
函数体内的this
对象,就是定义时所在的对象,而不是使用时所在的对象。this
不能够看成构造函数,也就是说,不可使用new
命令,不然会抛出一个错误。
不可使用arguments
对象,该对象在函数体内不存在。若是要用,能够用Rest参数代替。
不可使用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 一块儿用就会抛出错误。
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 });