关于 ES6 中的箭头函数
最近在看 ES6 的内容,遇到箭头函数(Arrow Function),便忍不住做些尝试,其实箭头函数在 c# 和 java 8.0 中早已普及,也就是所谓的 lambda 表达式,接下去我们会尝试一些箭头函数的定义和使用,若是有错误的地方,还请大家不吝赐教~
箭头函数(Arrow Function) 的兼容性
ios safari 从版本 10 以后都支持,chrome 从版本 49 以后都支持,故而本文示例需要在较新的浏览器或是 nodejs 环境中运行,一下附上 caniuse 中关于箭头函数的详细兼容性列表
箭头函数(Arrow Function) 的语法
一般语法
1 | // 一般写法 |
高阶语法
1 | // 返回文字表达式,此处需要用 () 将表达式包起来 |
箭头函数(Arrow Function) 的用途和特性
更短的语法
1 | var array = [1,2,3,4]; |
箭头表达式会捕获定义时其上下文的 this 值作为自己的 this
我们先看一个例子,在 ES3 和 ES5 的语法中,每个新定义的函数都有自己的 this
- 构造函数的 this 指向一个构造出来的新的对象
- 函数作为对象的方法来调用,则 this 指向调用者
这样的行为会为我们的编程造成一些困惑,譬如:
1 | var count = { |
此处输出 NAN 是因为执行 setInterval 时,this 指针指向 myCount,而不再是 count,故而 this.current 的值变成了 undefined,执行 ++ 操作后,就变为了 NAN,我们可以手动保存 count 的 this 值去修正这个问题:
1 | var count = { |
在函数内部使用了事先保存好的 this 值,这样就不会有问题了,或是也可以用 ES5 中的 bind 函数,强制改变 this 的指向:
1 | var count = { |
有了箭头函数以后,我们就可以如下写法:
1 | var count = { |
箭头函数的 this 始终指向函数定义时的 this,且之后不会发生改变,故而以上写法是可以的
1 | var current = 1; |
此处箭头函数定义时,this 值为全局对象 window,故而 this.current 为 1 ,用 call 手动改变箭头函数的 this 指向无效,其会始终指向定义时的捕获的上下文的 this 值,故而输出的 this.current 仍旧是 1
没有内部 arguments
箭头表达式内部没有暴露 arguments 参数,若是在箭头函数中使用了 arguments 它则会指向箭头函数所在作用域中名为 arguments 的值,若没有,则为 undefined
1 | var arguments = 1; |
针对这个问题,我们可以用 rest 参数代理:
1 | function foo() { |
此处我们用 (…rest) 剩余参数和外层包裹的 foo 函数对 arguments 进行了代理,但是这么做没有必要,因为内外层的函数只是为了完成同一个函数的作用,部分失去了箭头函数便利性的特点。
不能使用 new 操作符
箭头函数由于没有构造器 constructor,故而不能使用 new 操作符
1 | var Foo = () => {}; |
没有原型属性
1 | var Foo = () => {}; |
返回文字表达式
{} 里面的代码会被解析为序列语句( foo 被认为是一个标签, 而非文字表达式的组成部分 ),所以使用文字表达式时一定要加 ( )
1 | var func = () => ({ foo: 1 }); // 正确 |