目录
1.箭头函数简介
2.箭头函数与普通函数的区别
A.声明方式不同,匿名函数
B.this指向不同
C.箭头函数的this永远不会变,call、apply、bind也无法改变
D.箭头函数没有原型prototype
E.箭头函数不能当成一个构造函数
F.箭头函数没有自己的arguments
1.箭头函数简介
// 箭头函数
let foo = (name) => `我是${name}`
foo('风继续吹') // 我是风继续吹
// 等同于下面这个普通函数
let foo2 = function(name) {
return `我是${name}`
}
箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }
和return
都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }
和return
:
let foo = (name) => {
if(name){
return `我是${name}`
}
return '前端风继续吹'
}
foo('风继续吹') // 我是南玖
这里需要注意的是如果箭头函数返回的是一个字面量对象,则需要用括号包裹该字面量对象返回
let foo = (name) => ({
name,
job: 'front end'
})
// 等同于
let foo2 = function (name) {
return {
name,
job: 'front end'
}
}
2.箭头函数与普通函数的区别
我们可以通过打印箭头函数和普通函数来看看两者到底有什么区别:
let fn = name => {
console.log(name)
}
let fn2 = function(name) {
console.log(name)
}
console.dir(fn) //
console.dir(fn2) //
从打印结果来看,箭头函数与普通函数相比,缺少了caller,arguments,prototype
A.声明方式不同,匿名函数
- 声明一个普通函数需要使用关键字
function
来完成,并且使用function
既可以声明成一个具名函数也可以声明成一个匿名函数 - 声明一个箭头函数则只需要使用箭头就可以,无需使用关键字
function
,比普通函数声明更简洁。 - 箭头函数只能声明成匿名函数,但可以通过表达式的方式让箭头函数具名
B.this指向不同
对于普通函数来说,内部的this
指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this
对象,内部的this
就是定义时上层作用域中的this
。也就是说,箭头函数内部的this
指向是固定的,相比之下,普通函数的this
指向是可变的。
var name = '风继续吹'
var person = {
name: 'front end',
say: function() {
console.log('say:',this.name)
},
say2: () => {
console.log('say2:',this.name)
}
}
person.say() // say: front end
person.say2() // say2: 风继续吹
这里第一个say
定义的是一个普通函数,并且它是作为对象person
的方法来进行调用的,所以它的this
指向的就是person
,所以它应该会输出say: front end
而第二个say2
定义的是一个箭头函数,我们知道箭头函数本身没有this
,它的this
永远指向它定义时所在的上层作用域,所以say2
的this
应该指向的是全局window,所以它会输出say2: 风继续吹
C.箭头函数的this永远不会变,call、apply、bind也无法改变
我们可以用call、apply、bind来改变普通函数的this指向,但是由于箭头函数的this指向在它定义时就已经确定了,永远指向它定义时的上层作用域中的this,所以使用这些方法永远也改变不了箭头函数this
的指向。
var name = '风继续吹'
var person = {
name: 'nanjiu',
say: function() {
console.log('say:',this.name)
},
say2: () => {
console.log('say2:',this.name)
}
}
person.say.call({name:'小明'}) // say: 小明
person.say2.call({name:'小红'}) // say2: 风继续吹
还是上面那个例子,只不过我们在调用的时候使用call
试图改变this
指向,第一个say
是一个普通函数,它经过call调用,打印出的是say: 小明
,这说明普通函数的this已经改变了,第二个say2
是一个箭头函数,它也经过call调用,但它打印出的仍然是say2: 风继续吹
,这就能够证明箭头函数的this永远不会变,即使使用call、apply、bind也无法改变
D.箭头函数没有原型prototype
let fn = name => {
console.log(name)
}
let fn2 = function(name) {
console.log(name)
}
console.log(fn.prototype) // undefined
console.dir(fn2.prototype) // {constructor: ƒ}
在这里补充一下prototype的相关知识点
E.箭头函数不能当成一个构造函数
为什么箭头函数不能当成一个构造函数呢?我们先来用new
调用一下看看会发生什么:
let fn = name => {
console.log(name)
}
const f = new fn('风继续吹')
报错:
F.箭头函数没有自己的arguments
箭头函数处于全局作用域中,则没有arguments
let fn = name => {
console.log(arguments)
}
let fn2 = function(name) {
console.log(arguments)
}
fn2() // Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
fn() // 报错 Uncaught ReferenceError: arguments is not defined
还是用这两个函数来比较,普通函数能够打印出arguments
,箭头函数使用arguments
则会报错,因为箭头函数自身是没有arguments的,然后它会往上层作用域中去查找arguments
,由于全局作用域中并没有定义arguments
,所以会报错。
可以使用rest参数代替arguments传入参数
ES6 引入 rest
参数,用于获取函数不定数量的参数数组,这个API是用来替代arguments
的,形式为...变量名
,rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
let fn3 = (a,...arr) => {
console.log(a,arr) //1, [2,3,4,5,6]
}
fn3(1,2,3,4,5,6)
上面就是rest参数的基本用法,需要⚠️注意的是:
rest
参数只能作为函数的最后一个参数// 报错 function f(a, ...b, c) { // ... }
- 函数的
length
属性,不包括rest
参数
备注:本文大量参考稀土掘金博主前端南玖相关知识点,若侵权请联系作者删除