ES6允许使用箭头(=>)定义函数
var f = v => v;
//等同于
var f = function(v){
return v;
}
如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。
var f = () => 5;
console.log(f());
//相当于
var f = function(){
return 5;
}
var sum = (num1,num2) => num1 + num2;
console.log(sum(1,2));
//相当于
var sum = function(sum1,sum2){
return sum1 + sum2;
}
如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且可以使用return 返回语句。
var f = () => {
var a = 1;
var b = 2;
return a + b;
}
console.log(f());
由于大括号被解释为代码块,所以如果箭头函数直接返回的一个对象,必须在对象外面加上大括号,否则会报错。
let func = id => { id : id, name : 'Temp'} //报错
let func = id => ({ id : id , name : 'wng'});
上面代码中,原始意图是返回一个对象{a : 1},但是由于引擎认为大括号是代码块,所以执行了一行语句 a : 1 。这是,a可以被解释为语句的标签,因此实际执行的语句是1,然后函数就结束了,没有返回值。
如果箭头函数只有一行语句,且不需要返回值,可以采用下面的写法,就不用写大括号了。
let fu = () => 1 + 2;
let fn = () => void fu();
console.log(fn());
箭头函数可以与变量解构赋值结合使用。
const full = ({first,last}) => first + " " +last;
console.log(full({first : 1, last : 2}));
箭头函数的一个用处是可以简化回调函数。
let arr2 = arr.map((x) => x = x + 1);
rest参数结合箭头函数。
const number = (...values) => values;
console.log(number(1,2,3,4,5,6,7,8,9));
const fun = (first,...last) => [first,last];
console.log(fun(1,2,3,4,5,6));
箭头函数的注意点
1.函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
2.不可以当做构造函数,也就是说不可以使用new命令,否则会抛出一个错误
3.不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以使用rest参数。
4.不可以使用yield命令,因此箭头函数不能用作Generator函数
第一点注意:this对象的指向是可变的,但是,在箭头函数中,它是固定不变的
var obj = {
fun : function(){
setTimeout(function(){
console.log(this);
},1000)
}
}
obj.fun(); //window
var obj1 = {
fun : function(){
setTimeout(() =>{
console.log(this);
},1000);
}
}
obj1.fun();
var obj2 = {
num : 123,
fun : function(){
console.log(this);
var f = () => {
console.log(this);
}
f();
setTimeout(() => {
console.log(this.num);
},1000);
}
}
obj2.fun()
//自己可以运行一下
箭头函数可以让this指向固定化,这种特性很有利于封装回调函数。但是,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正式因为它没有this,所以也就不能用作构造函数。
箭头函数转成ES5的代码如下
function foo(){ //ES6
setTimeout( () => {
console.log('id:',this.id);
},100);
}
//ES5
function foo(){
var _this = this;
setTimeout( () => {
console.log("id :" , _this.id);
})
}
除了this,以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量:arguments,super,new.target。
function foo(){
setTimeout( () => {
console.log(arguments); //callee :foo
},100);
}
foo(2,4,6,8);
//上面代码中,箭头函数内部的变量arguments,其实是函数foo的arguments变量
另外,由于箭头函数没有自己的this,所以当然也不能用call(),apply(),bind()这些方法去改变this的指向。
(function(){
return [
(() => this.x).bind({x : 'inner'})()
]
}).call({x : 'outer'});
//箭头函数没有自己的this,所以bind方法无效,内部的this指向外部的this
嵌套的的箭头函数:箭头函数内部,还可以再使用箭头函数。
function insert(value) {
return {
init : function (array){
return {
after : function(afterValue) {
array.splice(array.indexOf(afterValue) + 1,0,value);
return array;
}
}
}
}
}
console.log(insert(2).init([1,3]).after(1));
let insert = (value) => ({init : (array) => ({after : (afterValue) => {
array.splice(array.indexOf(afterValue) + 1 , 0 , value);
return array;
/ }})});
console.log(insert(2).init([1,3]).after(1));
部署管道机制:下面reduce方法中的b方法把a方法作为参数传过去,这个我也不理解这个执行过程。
const pipeline = (...funcs) => val => funcs.reduce((a,b) => b(a),val);
const plus1 = a => a + 1;
const mult2 = a => a * 2;
const addThenMult = pipeline(plus1,mult2);
console.log(addThenMult(5));
在别的地方看到别人写的ES5的形式,也就是addThenMult这个方法。
const addThenMult = function(num){
return pipeline(plus1(num),mult2)
}
//这里在plus1那里把参数传了进去,我也不懂这个地方