ES6中的箭头函数=>

2020-10-26 11:15:10 浏览数 (2)

ES6标准新增了一种新的函数:Arrow Function(箭头函数)。为什么叫Arrow Function?因为它的定义用的就是一个箭头:

代码语言:javascript复制
x => x * x

相当于:

代码语言:javascript复制
function(x){
  return x*x;
}

箭头函数相当于匿名函数,并且简化了函数定义。

箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }和return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }和return:

代码语言:javascript复制
x => {
    if (x > 0) {
        return x * x;
    }
    else {
        return - x * x;
    }
}

如果参数不是一个,就需要用括号()括起来:

代码语言:javascript复制
// 两个参数:
(x, y) => x * x   y * y

// 无参数:
() => 3.14

// 可变参数:
(x, y, ...rest) => {
    var i, sum = x   y;
    for (i=0; i<rest.length; i  ) {
        sum  = rest[i];
    }
    return sum;
}

如果要返回一个对象,就要注意,如果是单表达式,这么写的话会报错:

代码语言:javascript复制
// SyntaxError:
x => { foo: x }

因为和函数体的{ ... }有语法冲突,所以要改为:

代码语言:javascript复制
// ok:
x => ({ foo: x })

this

箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。

回顾前面的例子,由于JavaScript函数对this绑定的错误处理,下面的例子无法得到预期结果:

代码语言:javascript复制
var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = function () {
            return new Date().getFullYear() - this.birth; // this指向window或undefined
        };
        return fn();
    }
};

现在,箭头函数完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj:

代码语言:javascript复制
var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
        return fn();
    }
};
obj.getAge(); // 25

更多箭头函数示例如下:

代码语言:javascript复制
// 空的箭头函数返回 undefined
let empty = () => {};

(() => 'foobar')(); 
// Returns "foobar"
// (这是一个立即执行函数表达式,可参阅 'IIFE'术语表) 


var simple = a => a > 15 ? 15 : a; 
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

// Easy array filtering, mapping, ...

var arr = [5, 6, 13, 0, 1, 18, 23];

var sum = arr.reduce((a, b) => a   b);  
// 66

var even = arr.filter(v => v % 2 == 0); 
// [6, 0, 18]

var double = arr.map(v => v * 2);       
// [10, 12, 26, 0, 2, 36, 46]

// 更简明的promise链
promise.then(a => {
  // ...
}).then(b => {
  // ...
});

// 无参数箭头函数在视觉上容易分析
setTimeout( () => {
  console.log('I happen sooner');
  setTimeout( () => {
    // deeper code
    console.log('I happen later');
  }, 1);
}, 1);


var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

0 人点赞