ES6 箭头函数

Posted ericzlin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6 箭头函数相关的知识,希望对你有一定的参考价值。

一、定义函数的三种方式

①函数声明

      function f1(){
          console.log(‘aaa‘)
      }  

②函数表达式

    var f2=function(){
        console.log(‘bbb‘)
    } 

③构造函数实例化new

    var f3 = new Function(‘a‘, ‘b‘, ‘console.log(a+b)‘);
    f3(2,10);//12

二、箭头行数简写

①ES6 允许使用“箭头”(=>)定义函数。只能简写函数表达式方式定义函数,不能简写函数声明或者构造函数new的方式定义函数。

②一个参数可以省略(),函数体只有一条语句,可以省略 { },并默认return。如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。

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;
};

③由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

// 报错
let getTempItem = id => { id: id, name: "Temp" };

// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });

④箭头函数可以与变量解构结合使用。

const full = ({ first, last }) => first + ‘ ‘ + last;

// 等同于
function full(person) {
  return person.first + ‘ ‘ + person.last;
}

⑤箭头函数使得表达更加简洁。

const isEven = n => n % 2 == 0;
const square = n => n * n;
// 正常函数写法
[1,2,3].map(function (x) {
  return x * x;
});

// 箭头函数写法
[1,2,3].map(x => x * x);
// 正常函数写法
var result = values.sort(function (a, b) {
  return a - b;
});

// 箭头函数写法
var result = values.sort((a, b) => a - b);

⑥不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替

const numbers = (...nums) => nums;

numbers(1, 2, 3, 4, 5)
// [1,2,3,4,5]

const headAndTail = (head, ...tail) => [head, tail];

headAndTail(1, 2, 3, 4, 5)
// [1,[2,3,4,5]]

三、箭头函数内部this指向问题

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

this对象的指向是可变的,但是在箭头函数中,它是固定的。

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

var id = 21;

foo.call({ id: 42 });
// id: 42
/*setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到 100 毫秒后。如果是普通函数,执行时this应该指向全局对象window,这时应该输出21。但是,箭头函数导致this总是指向函数定义生效时所在的对象(本例是{id: 42}),所以输出的是42。*/

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

function Timer() {
  this.s1 = 0;
  this.s2 = 0;
  // 箭头函数
  setInterval(() => this.s1++, 1000);
  // 普通函数
  setInterval(function () {
    this.s2++;
  }, 1000);
}

var timer = new Timer();

setTimeout(() => console.log(‘s1: ‘, timer.s1), 3100);
setTimeout(() => console.log(‘s2: ‘, timer.s2), 3100);
// s1: 3
// s2: 0

④箭头函数可以让this指向固定化,这种特性很有利于封装回调函数。

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);
  }
};

this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数。

ES5里解决this指向的问题,一个就是使用下面的this备份,还有可以借助bind(this)的方法。

可以理解为箭头函数自动bind(this)外部环境,所以箭头函数也无法通过call、apply、bind来手动设置内部的this指向,它内部的this都是取决于外部环境。

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

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

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

        // ES5:bind(this)
        function foo() {
            setTimeout(function () {
                console.log(‘id:‘, this.id);
            }.bind(this), 100);
        }

以上是关于ES6 箭头函数的主要内容,如果未能解决你的问题,请参考以下文章

类属性中的 es6 箭头函数

ES6 箭头函数

ES6新特性2:箭头函数

学习ES6箭头函数

ES6新特性2:箭头函数

ES6 箭头函数是不是与 Angular 不兼容?