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

176 阅读2分钟

箭头函数是ES6中,提供的一个新的API,因为语法简介,写起来方便,深受广大前端人欢迎,那它与普通的函数有什么区别呢。

一、写法上

1、使用箭头=>来表示,语法简单

// 箭头函数
let a = (name)=>{
	return `Hello, ${name}`
}
// 普通函数
function b(name){
	return `Hello, ${name}`
}

2、简单函数的话,可以不用return

let a = (name) => name
//如果有简单的表达式也可以省略括号
let a = (name) => name + 'hello';
// 如果返回对象,需要在括号内,否则花括号会被认为是函数体
let a = (name) => ({return `Hello, ${name}`})

//如果不需要返回值
let a = () => void noReturn();

3、参数只有一个的话,可以省略括号,如果没有参数,可以写个空的括号

let a = name => ({return `Hello, ${name}`})

// 如果没有参数
let a = () => ({return `Hello`})

4、箭头函数不绑定arguments,取而代之用rest参数,如果在箭头函数内使用 arguments ,那么这个arguments是外层的值。可以使用rest参数...来代替, arguments并非数组,是个类数组,通过Object.prototype.toString.call(arguments),得到的结果为: [object Arguments]

function a(params){
	console.log(arguments);
}
a(1,2,3,4,5) // [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
let b = (params)=>{ console.log(arguments)};
b(1,2,3,4,5) // Uncaught ReferenceError: arguments is not defined

let c = (...params)=>{ console.log(params)}; // 数组 [1, 2, 3, 4, 5]

二、语法及执行环境

1、箭头函数没有prototype,所以箭头函数本身没有this;

let a = ()=>{};
console.log(a.prototype); // undefined

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

2、箭头函数不能作为构造函数使用 我们先了解一下构造函数的new都做了什么?

  • JS内部先生成一个对象
  • 连接到原型
  • 绑定this
  • 最终返回该对象 手动实现new请参考 juejin.cn/post/690607… 但是箭头函数没有自己的this,它指向的是外层执行环境中的this,并且不会改变,所以构造函数不能定义成箭头函数,否则new调用会报错。
let Func = (name,age) => {
	this.name = name;
    this.age = age;
    console.log(this.name + ' is ' + this.age)
}
let p = new Func('xiaoming',8) // Uncaught TypeError: Func is not a constructor
Func('xiaoming',8) // xiaoming is 8;可以调用

3、箭头函数的 this 指向在定义函数的时候,继承自外层第一个普通函数的this,并且之后不会被改变。所以,call | apply | bind 也无法改变箭头函数的this指向

let obj = {
  a:1,
  b:()=>{
    console.log(this.a); // undefined
    console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …};
  },
  c:function(){
    console.log(this.a); // 1
    console.log(this); // {a: 1, b: ƒ, c: ƒ}
  }
}

obj.b(); 
obj.c();

// call bind apply
var id = 1;
let fun = () => {
    console.log(this.id)
};
fun();     // 1
fun.call({ id: 2 });     // 1
fun.apply({ id: 2 });    // 1
fun.bind({ id: 2 })();   // 1