箭头函数是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