js箭头函数

162 阅读3分钟

基础语法

(param1, param2, …, paramN) => { statements }

(param1, param2, …, paramN) => expression

//相当于:(param1, param2, …, paramN) =>{ return expression; }

singleParam => { statements }// 当只有一个参数时,圆括号是可选的:

() => { statements }// 没有参数的函数应该写成一对圆括号

高级语法

//加括号的函数体返回对象字面量表达式:
params => ({foo: bar})

//支持剩余参数和默认参数
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
statements }

//同样支持参数列表解构
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();  // 6

当箭头函数的函数体只有一个 return 语句时,可以省略 return 关键字和方法体的花括号

引入箭头函数的作用

两个方面的作用:更简短的函数并且不绑定this。

更短的函数

使函数更简洁、更短的一个例子:

var elements = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

elements.map(function(element) {
  return element.length;
}); // 返回数组:[8, 6, 7, 9]

// 在这个例子中,因为我们只需要 `length` 属性,所以可以使用参数解构
// 需要注意的是字符串 `"length"` 是我们想要获得的属性的名称,而 `lengthFooBArX` 则只是个变量名,
// 可以替换成任意合法的变量名
elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]

箭头函数不绑定this

箭头函数与普通函数中this对比

下面的例子中:

由setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字在非严格模式会指向 window (或全局)对象,严格模式下为 undefined,这和所期望的this的值是不一样的。

备注:即使是在严格模式下,setTimeout()的回调函数里面的this仍然默认指向window对象, 并不是undefined。

以上参考MDN文档中developer.mozilla.org/zh-CN/docs/…

function Person() {
  // Person() 构造函数定义 `this`作为它自己的实例.
  this.age = 0;

  setInterval(function growUp() {
    // 在非严格模式, growUp()函数定义 `this`作为全局对象,
    // 与在 Person()构造函数中定义的 `this`并不相同.
    this.age++;
  }, 1000);
}

var p = new Person();

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。因此,在下面的代码中,传递给setInterval的函数内的this与封闭函数中的this值相同:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| 正确地指向 p 实例
  }, 1000);
}

var p = new Person();

通过call或apply调用

由于 箭头函数没有自己的this指针,通过 call() 或 apply() 方法调用一个函数时,只能传递参数,不能绑定this,他们的第一个参数会被忽略。(这种现象对于bind方法同样成立---译者注)

不绑定arguments

箭头函数不绑定argumrnts对象,

其他特性

箭头函数不能用作构造器,和 new一起用会抛出错误。

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

箭头函数没有prototype属性。

var Foo = () => {};
console.log(Foo.prototype); // undefined

返回对象字面量

要用圆括号把对象字面量包起来:

var func = () => ({ foo: 1 });

var func = () => ({ foo: function() {} });

换行

箭头函数在参数和箭头之间不能换行。

但是,可以通过在 ‘=>’ 之后换行,或者用 ‘( )’、'{ }'来实现换行

var func = (
  a,
  b,
  c
) => 1;

// 不会有语法错误

箭头函数使用闭包:

//箭头函数体的闭包( i=0 是默认参数)
var Add = (i=0) => {return (() => (++i) )};
var v = Add();
v();           //1
v();           //2

//更简短的写法如下
//因为仅有一个返回,return 及括号()也可以省略
var Add = (i=0)=> ()=> (++i);

注意细节:

  • // 空的箭头函数返回 undefined
// 空的箭头函数返回 undefined
let empty = () => {};
  • 箭头函数可以有一个“简写体”或常见的“块体”。

在一个简写体中,只需要一个表达式,并附加一个隐式的返回值。在块体中,必须使用明确的return语句。