最近室友面试,又问到了这个问题,索性自己也整理整理,希望看到的大佬们也帮忙补充补充,感谢感谢!
MDN解释如下:箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super 或 new.target
。
箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
function Person1() {
this.age = 0
setTimeout(() => {
console.log(this.age)
// |this| 正确地指向 p1 实例 所以打印为0
}, 1000)
}
var p1 = new Person1()
/*
箭头函数不会创建自己的 this,它只会从自己的作用域链的上一层继承 this
因此,在上面的代码中,传递给 setTimeout 的函数内的this与封闭函数中的this值相同
*/
function Person2() {
this.age = 0
setTimeout(function () {
console.log(this.age)
// |this| 指向 window 所以打印为undefined
}, 1000)
}
var p2 = new Person2()
/*
在非严格模式,setTimeout() 函数定义 `this`作为全局对象,
与在 Person2() 构造函数中定义的 `this`并不相同
*/
function Person3() {
let that = this
this.age = 0
setTimeout(function () {
// 回调引用的是`that`变量,其值是预期的对象。正确地指向 p3 实例 所以打印为0
console.log(that.age)
}, 1000)
}
var p3 = new Person3()
/*
通过将 this 值分配给封闭的变量,可以解决 this 问题。
*/
注意点:
1、箭头函数不能用作构造器,和 new一起用会抛出错误。
2、箭头函数没有prototype属性。
3、 yield 关键字通常不能在箭头函数中使用(除非是嵌套在允许使用的函数内)。因此,箭头函数不能用作函数生成器。
说到普通函数,普通函数的实际参数会被保存在一个类似数组的 arguments 对象
中。
arguments[i]
其中i是参数的序数编号(译注:数组索引),以 0 开始。所以第一个传来的参数会是arguments[0]。参数的数量由arguments.length表示。
使用 arguments 对象,可以处理比声明的更多的参数来调用函数。这在你事先不知道会需要将多少参数传递给函数时十分有用。
你可以用arguments.length来获得实际传递给函数的参数的数量,然后用arguments对象来取得每个参数。
备注:arguments变量只是 ”类数组对象“,并不是一个数组。称其为类数组对象是说它有一个索引编号和length属性。尽管如此,它并不拥有全部的 Array 对象的操作方法。
function func() {
console.log(arguments)
// Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}
func(1, 2, 3)
this指向不同:
1、普通函数,谁调用this ,this就指向谁;
2、箭头函数,在哪里定义函数, this就指向谁(可以理解为,内部的箭头函数不会改变this指向对象的,this仍然指向外面函数的作用域)
补充:
箭头函数内的this指向上层对象,bind()、call()、apply()均无法改变指向。
普通函数内的this执行调用其函数的对象。
可以说普通函数的this指向是不固定的;
let obj = {
a: 10,
f1: () => {
console.log(this, this.a)
},
f2: function () {
console.log(this, this.a)
}
}
obj.f1() // Window undefined
obj.f2() // {a: 10, f1: ƒ, f2: ƒ} 10
1、箭头函数表达式的语法比函数表达式更简洁;
2、 箭头函数不会创建自己的this,所以它没有自己的this,它只会从自己的作用域链的上一层继承this;
3、箭头函数继承而来的this指向永远不变,是继承的它定义时所处的全局执行环境, 之后不再改变;
4、箭头函数继承而来的this指向永远不变,call()、apply()、bind()无法改变箭头函数中this的指向;
5、箭头函数不能作为构造函数使用,不能使用new关键字;
6、箭头函数没有自己的arguments,可以使用拓展运算符代替;
7、箭头函数没有原型prototype,prototype是普通函数用于获取原型对象的;
8、箭头函数不能用作Generator函数,不能使用yeild关键字;