ES6常用新特性学习4-箭头函数

1. 简介

也许我们已经习惯了在定义函数时使用:

function f(){
  ...
}

这样的写法。但是ES6 提供了新的函数定义方法,即箭头函数。不仅在写法上简化了代码量,而且更重要的是提供了新的this指向。大家可以对比我之前的文章JS入门难点解析7-this进行阅读。

2. 基本用法

箭头函数的基本用法如下:
参数部分使用一对圆括号包围,函数体部分使用一对花括号包围,参数与函数体使用箭头连接。

var add = (num1, num2) => {
    var sum = num1 + num2
    return sum; 
};

等同于

var add = function(num1, num2) {
    var sum = num1 + num2
    return sum; 
};

如果参数没有参数,仅需一对圆括号即可:

var getFive = () => {
    return 5;
};

如果仅有一个参数,可以省略圆括号:

var getNum= num => {
    return num;
};

如果函数体只有一条语句,可以省略花括号

var getNum= num => num;

3. this固定化

我们来看一个例子:

function foo() {
  setTimeout(function() {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 21

这段代码中,foo的this指向的是{id: 42},但是setTimeout中的匿名函数在执行时其this指向的是全局。(可以参考我的文章JS入门难点解析7-this)但是,如果从写代码的人的角度去思考,很明显是希望此处匿名回调函数的this是指向call的对象的。

箭头函数可以让setTimeout里面的this,绑定定义时所在的作用域,而不是指向运行时所在的作用域。

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

看上去很神奇,仿佛箭头函数改变了this的绑定。但其实不然。this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

所以,箭头函数转成 ES5 的代码如下。

// ES6
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

// ES5
function foo() {
  var _this = this;

  setTimeout(function () {
    console.log('id:', _this.id);
  }, 100);
}

上面代码中,转换后的 ES5 版本清楚地说明了,箭头函数里面根本没有自己的this,而是引用外层的this。所以这种this的固定化是一种语法糖,本质上和我们以前使用的var that = this;的写法是一致的。

箭头函数可以让this指向固定化的特性很有利于封装回调函数。下面是一个例子,DOM 事件的回调函数封装在一个对象里面。

var handler = {
  id: '123456',

  init: function() {
    document.addEventListener('click',
      event => this.doSomething(event.type), false);
  },

  doSomething: function(type) {
    console.log('Handling ' + type  + ' for ' + this.id);
  }
};

上面代码的init方法中,使用了箭头函数,这导致这个箭头函数里面的this,总是指向handler对象。否则,回调函数运行时,this.doSomething这一行会报错,因为此时this指向document对象。

3. 使用注意点事项

箭头函数有几个使用注意事项。

(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替(就是使用展开符)。

(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

参考

函数的扩展
ES6这些就够了

你可能感兴趣的:(ES6常用新特性学习4-箭头函数)