JavaScript 箭头函数和普通函数的区别

130 阅读1分钟

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

const fn1 = () =>{ 

}

function fn2(){

}

console.log(fn1.prototype);   // undefined
console.log(fn2.prototype);   // {constructor: ƒ}

二、箭头函数不绑定this

  • 箭头函数不绑定this,它会捕获其定义时的位置上下文的this值, 作为自己的this值

  • 普通函数的this值,在调用的时候确认,也就是在生成函数执行上下文时候确认的

let p = {
  a: function () {
    var obj = {
      b: () => {console.log(this)},
    }
    obj.b()
  }
}
p.a() // {a: ƒ} 函数执行上下文的this值

三、箭头函数不绑定 arguments,取而代之用rest参数...解决

function fn1(a){
  console.log(arguments);
}
fn1(1,2,3);  //  [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]

const fn2 = (...rest) => {
  console.log(rest);
}
fn2(1,2,3);  // [1,2,3]

四、call、apply、bind不会改变箭头函数this值,会改变普通函数this值

const obj = {
    a: 10,
    b: function() {
        const c = { a: 20 }
        console.log(this) // {a: 10, b: ƒ}
        const fn = () => {
           console.log(this) // {a: 10, b: ƒ}
        };
        return fn.call(c)
    }
};
console.log(obj.b())

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

// 构造函数生成实例的过程
function Person(name,age){
    this.name = name
    this.age = age
}
var p = new Person('张三',18)
console.log(p) // Person {name: '张三', age: 18}

// new关键字生成实例过程如下

// 1. 创建空对象p
var p = {} 

// 2. 将空对象p的原型链指向构造器Person的原型
// 若此处Person为箭头函数,没有原型属性,也就无法将原型赋值给 p.__proto__
p.__proto__ = Person.prototype

// 3. 将Person()函数中的this指向p
// 若此处Person为箭头函数,而没有自己的this,call()函数无法改变箭头函数的指向,也就无法指向p。
Person.call(p) 

六、箭头函数不能当做Generator函数,不能使用yield关键字