当下不可不知的es6箭头函数
相信各位大侠对ES6并不陌生了,所以在此不再赘述它的历史与由来,直接进入正题。
jQuery的这种写法可能已经被写烂了:
$(".submit-btn").click(function(){ ajax(); });
那么来个新鲜的:
$(".submit-btn").click(() => ajax());
第一次接触箭头函数的写法,似乎觉得无法理解,别急,我们先来了解一下ES6箭头函数的基本语法:
([param], [param]) => { statements } // param 是参数,根据参数个数不同,分这几种情况: // () => { … } 零个参数用()表示function; // x => { … } 一个参数时可以省略(); // (x, y) => { … } 多参数不能省略()
看过语法后,是不是觉得箭头函数简洁明了,至少不用写function了,不会再出现因为function写成functoin而报错的尴尬了。那么箭头函数的好处仅此而已吗?如果仅仅如此,那当然是太肤浅了。
当function函数体中只有一句return语句时,也可将return省略。
// ES5
var total = values.reduce(function (a, b) { return a + b; }, 0);
// ES6
var total = values.reduce( (a, b) => a + b, 0 ); // 两个参数a,b ,所以参数外层的 () 不可省略
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;
}
只有一些省略单词的功能吗?of course NO !
对于传统function函数,都有属于自己的this值,使得内层函数的this值可能是window、undefined或者内层函数自身的对象,这也制造了不少麻烦,比如我们写过这段hack用来处理this的指向问题:
// ES5 { ... add: function(arr){ var that = this; _.each(arr, function (item) {
// 此函数里的this并不是可以调用add方法的对象,需要用that保存外层可以调用add方法的this对象
that.add(item);
})
}
...
}
假如函数嵌套太深,this问题是很头疼的,此时轮到箭头函数登场了,箭头函数可以继承外围作用域的this
值:
// ES6 {
... add(arr) => {
// 这里的this继承自外层对象的this,而不是each方法中自己的this
_.each( arr, item => this.add(item) )
}
... }
在ES6的版本中,add方法从它的调用者处获取了this
值,而其内部函数是一个箭头函数,所以该箭头函数继承了外围作用域的this
值。
另外,箭头函数还可以与ES6新特性“变量解构”结合使用,十分方便,想了解的请戳变量解构
// ES5 function full(obj) { return obj.name + ',' + obj.age; }
// ES6 const full = ({ name, age }) => name + ',' + age; // 只有一句代码所以省略return
学习了箭头函数的几种基本用法,我来提几点需要注意的地方,防止大家在用的过程中踩雷。
1、由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
var getObj = id => ({ id: id, name: "objName" });
var getObj = id => { id: id, name: "objName" }; // 报错
2、箭头函数与非箭头function函数间有一个细微的区别,箭头函数没有它们自己的arguments对象。
function showArgs() { setTimeout(() => { console.log('args:', arguments); }, 100); } showArgs(1, 3, 5) // args: [1, 3, 5] 这里的argments实际上是showArgs的arguments
3、箭头函数不可当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。原因是它没有属于自己的this。
4、箭头函数无法使用call()、apply()、bind()等方法改变this指向,因为它并没有this值。
(function() { return [ (() => this.x).bind({ x: 'inner' })() ]; }).call({ x: 'outer' });
// ['outer'] 箭头函数的bind()方法无效