箭头函数特点

定义:箭头函数是se6新定义的函数形式,语法比函数表达式更简洁,并且没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

箭头函数特点:

1.语法简单:

使用较为简洁的语法、较少的代码量来完成和普通函数一样的函数,例如:

//普通函数
[1,2,34,5].forEach(function(item,index){
console.log(item,index)
})
//箭头函数
[1,2,3,4,5,6].forEach((item,index)=>console.log(item,index))

2.不绑定this

在es5中我们知道函数中this指向问题,得出一个结论:this永远指向函数调用者,但是在箭头函数中,没有this,所以他的指向移动定义时候的所在环境,比如函数的执行期环境,对象环境或者window,例如:

//函数this指向window
let test = ()=>console.log(this)
test()//window
//对象中this指向
let obj = {
    name: 'jeck',
    test1: function(){console.log(this)},
    test2: ()=>console.log(this)
}
obj.test1()//{name: "jeck", test1: ƒ, test2: ƒ}
obj.test2()//window
//函数的this指向
function Person() {  
    this.age = 0;  
    this.num = 0;
    setTimeout(() => {
        this.age++;
        console.log(this.age)//1
    }, 3000);
    setTimeout(function(){
        this.num++;
        console.log(this.num)//NaN
    }, 3000);
}
var p = new Person();

在上面代码中,分别在window,对象和函数中分别使用普通函数和箭头函数,输出的值都不一样,使用settimeout,普通函数的this指向是调用者,调用者为window全局对象,没有全局属性,就会报错;箭头函数的this指向为函数定义者,所以可以获取到对应的值。

3.不支持call()和apply()函数的特性

我们都知道call和apply方法可以改变一个函数执行主体,即改变调用函数中this指向,但是箭头函数不能达到这一点,因为他没有this,是继承父作用域的this

let adder = {
  base : 1,
    
  add : function(a) {
    var f = v => v + this.base;
    return f(a);
},
  
  addThruCall: function(a) {
    var f = v => v + this.base;
        var b = {
      base : 2
    };   
    return f.call(b, a);
}
  };

console.log(adder.add(1));         // 2
console.log(adder.addThruCall(1)); // 2

执行adder.add(1)时,add()函数内部通过箭头函数的形式定义了f()函数,f()函数中的this会继承至父作用域,即adder,那么this.base = 1,因此执行adder.add(1)相当于执行1 + 1的操作,结果输出“2”。
执行adder.addThruCall(1)时,addThruCall()函数内部通过箭头函数定义了f()函数,其中的this指向了adder。虽然在返回结果时,通过call()函数调用了f()函数,但是并不会改变f()函数中this的指向,this仍然指向adder,而且会接收参数a,因此执行adder.addThruCall(1)相当于执行1 + 1的操作,结果输出“2”。
因此在使用call()函数和apply()函数调用箭头函数时,需要谨慎。

4.不绑定arguments

在普通函数中可以使用arguments来获取实际传入的参数值,但是在箭头函数中,我们却无法做到这一点。

const fn = () => {
    console.log(arguments);
};
fn(1, 2); // Uncaught ReferenceError: arguments is not defined

因为无法在箭头函数中使用arguments,同样也就无法使用caller和callee属性。
虽然我们无法通过arguments来获取实参,但是我们可以借助rest运算符(...)来达到这个目的。

const fn = (...args) => {
    console.log(args); 
};
fn(1, 2); // [1, 2]

箭头函数不适用的场景:

1.不适合作为对象的函数

在上面代码中,我有讲到箭头函数并不会绑定this,如果使用箭头函数定义对象字面量的函数,那么其中的this将会指向外层作用域,并不会指向对象本身,因此箭头函数并不适合作为对象的函数。

2. 不能作为构造函数

不能使用new操作符
构造函数是通过new操作符生成对象实例的,生成实例的过程也是通过构造函数给实例绑定this的过程,而箭头函数没有自己的this。因此不能使用箭头函数作为构造函数,也就不能通过new操作符来调用箭头函数。

function Person(name) {
    this.name = name;
}
var p = new Person('kingx'); // 正常
// 箭头函数
let Person = (name) => {
    this.name = name
};
let p = new Person('kingx'); // Uncaught TypeError: Person is not a constructor

3. 没有prototype属性

因为在箭头函数中是没有this的,也就不存在自己的作用域,因此箭头函数是没有prototype属性的。

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

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

希望对大家有用,感谢支持!

posted @ 2021-08-24 11:37  鸡腿太小  阅读(672)  评论(0编辑  收藏  举报