您的当前位置:首页>全部文章>文章详情

ES6 箭头函数讲解 你正确使用了吗?

发表于:2021-07-22 17:03:20浏览:1999次TAG: #箭头函数 #javascript #ES6

箭头函数是es6的一种函数的简写方法。在ES6中允许使用“箭头”(=>)定义函数,之前没有接触过箭头函数的人可能会惊讶于其代码的简洁。

一、先来几个简单的箭头函数

var f = v = > v;
//等同于
var f = function(v){
  return v;
}
var sum = (num1,num2) => num1+num2 ;
//等同于
var sum = function(num1,num2){
  return num1+num2
}
[1,2,3].map(function (x) {
  return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);//简洁了许多


从例子我们可以看出,函数省略了function,花括号‘{}’用‘=>’代替了,这种写法更简洁了。

除了简洁之外,箭头函数还有另外一个优点,就是函数体内的this的指向始终是指向定义它所在的对象,而不会指向调用它的对象,我们知道es5中的函数是谁执行它,它就指向谁。

二、箭头函数的用法

1、如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。

const hello = () => 'hello';
const sum = (num1, num2) => num1 + num2;


2、如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。

const sum = (x, y) => { 
  let z= 0; 
  if(x && y){
    z= x + y;
  }
  return z;
}


3、如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

const getInfo = id => ({ id: id, name: "hello" });

三、箭头函数注意事项

A、箭头函数的this指向

对于普通函数来说,内部的this指向函数运行时所在的对象。箭头函数没有自己的this对象,内部的this就是定义时上层作用域中的this。箭头函数this为父作用域的this,不是调用时的this,箭头函数的this永远指向其父作用域,任何方法都改变不了,包括call,apply,bind。

箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。

将ES6转成ES5,发现其实只是所谓的箭头函数的this只是从外面”借“来的。

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

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

在setInterval中,其实是没有this.s2的,所以它的值不会变化。

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

s1 // 1
s2 // 0

普通函数修改之后可以修改s2

//普通函数
setInterval(function () {
  let _this = this;
  _this.s2++;
}, 1000);

在这里也能看到箭头函数的this的指向,可以发现箭头函数非常适合来做回调。

B、箭头函数不能作为构造函数,不能使用new.

//构造函数如下:
function Person(p){
    this.name = p.name;
}
//如果用箭头函数作为构造函数,则如下
var Person = (p) => {
    this.name = p.name;
}

由于this必须是对象实例,而箭头函数是没有实例的,不能作为构造函数,这个好理解。因为箭头函数根本没有自己的this,拿甚构造?所以箭头函数也就不能用作构造函数。也不能使用new关键词。

C、箭头函数没有arguments,caller,callee。

像this一样,arguments指向外层函数的对应变量,像类似的兄弟还有super、new.target

function hello() {
  setTimeout(() => {
    console.log('args:', arguments);
  }, 1000);
}

hello(1,2,3,4)
// args: [1, 2, 3, 4]

也因为这个this的问题,箭头函数也不能用call()、apply()、bind()这些方法去改变this的指向,因此箭头函数的this是”静态“的。


D、箭头函数通过call和apply调用,不会改变this指向,只会传入参数

let obj2 = {
    a: 10,
    b: function(n) {
        let f = (n) => n + this.a;
        return f(n);
    },
    c: function(n) {
        let f = (n) => n + this.a;
        let m = {
            a: 20
        };
        return f.call(m,n);
    }
};
console.log(obj2.b(1));  // 11
console.log(obj2.c(1)); // 11


E、 箭头函数没有原型属性

var a = ()=>{
  return 1;
}

function b(){
  return 2;
}

console.log(a.prototype);  // undefined
console.log(b.prototype);   // {constructor: ƒ}


F、箭头函数返回对象时,要加一个小括号

var func = () => ({ foo: 1 }); //正确
var func = () => { foo: 1 };   //错误