es6允许使用“箭头”(=>)定义函数。
var f = v => v // 等同于 var f = function(v) { return v }
如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。
var f = () => 5 // 等同于 var f = function() { return 5 } var sum = (num1, num2) => num1 + num2 // 等同于 var sum = function(num1, num2) { return num1 + num2 }
如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。
var sum = (num1, num2) => {return num1 + num2}
由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
// 报错 let getTempItem = id => {id: id, name: "Temp"} // 不报错 let getTempItem = id => ({id: id, name: "Temp"})
下面是一种特殊情况,虽然可以运行,但会得到错误的结果。
let foo = () => {a: 1}
上面代码中,原始意图是返回一个对象{a: 1},但是由于引擎认为大括号是代码块,所以执行了一行语句a: 1,这时,a可以理解为语句的标签,因此实际执行了语句是1,然后函数就结束了,没有返回值。
如果箭头函数只有一行语句,且不需要返回值,可以采用下面的写法,就不用写大括号了。
let fn = () => void doesNotReturn()
箭头函数可以与变量解构结合使用。
const full = ({first, last}) => first + ' ' + last // 等同于 function full(person) { return person.first + ' ' + person.last }
箭头函数使用表达更简洁。
const isEven = n => n % 2 === 0 const square = n => n * n
箭头函数的一个用处是简化回调函数。
// 正常函数写法 [1, 2, 3].map(function(x) { return x * x }) // 箭头函数写法 [1, 2, 3].map(x => x * x)
下面是rest参数与箭头函数结合的例子。
const numbers = (...nums) => nums numbers(1, 2, 3, 4, 5) const headAndTail = (head, ...tail) => [head, tail] headAndTail(1, 2, 3, 4, 5)
使用注意点
1)函数体内的this对象,就是定义所在的对象,而不是使用时所在的对象。
2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
3)不可以使用arguments对象,该对象在函数体内不存在,如果要用,可以用rest参数代替。
4)不可以使用yield命令,因此箭头函数不能用作Generator函数。
function foo () { setTimeout(() => { console.log('id: ', this.id) }, 100) } var id = 21 foo.call({id: 42})
上面代码中,setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到100ms后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象,所在输出的是42.
箭头函数根本没有自己的this,导致内部的this就是外层代码块的this,正是因为它没有this,所以也就不能用作构造函数。
除了this,以下三个变量在箭头函数之中也是不存在的:
arguments, super, new.target
别外,由于箭头函数没有自己的this,所以当然也就不能用call(),apply(),bind()这些方法去改变this的指向。
(function() { return [ (() => this.x).bind({x: 'inner'})() ] }).call({x: 'outer'})
不适用场合
由于箭头函数使得this从“动态”变成“静态”,下面两个场合不应该使用箭头函数。
第一个场合是定义函数的方法,且该方法内部包括this.
window.lives = 100 var cat = { lives: 9, jumps: () => { this.lives--; console.log(this.lives)} } // 99
上面代码中,cat.jumps()方法是一个箭头函数,这是错误的。调用cat.jumps()时,如果是普通函数,该方法内部的this指向cat;如果写成上面那样的箭头函数,使得this指向全局对象,因些不会得到预期结果。
第二个场合是需要动态this(事件监听)的时候,也不应该使用箭头函数。
var button = document.getElementById('press'); button.addEventListener('click', () => { this.classList.toggle('on'); });
上面代码运行时,点击按钮会报错,因为button的监听函数是一个箭头函数,导致里面的this就是全局对象。如果改成普通函数,this就会动态指向被点击的按钮对象。
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:测试上述代码运行效果。
更多关于JavaScript相关内容可查看本站专题:《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》及《JavaScript数学运算用法总结》