箭头函数,我们常常会用到,那它在使用上和常规函数有什么区别呢?我们来一起看看哈
先来定义一个普通函数,一个箭头函数,分别看一下它们的结构
function abc(){}
console.dir(abc)
通过查看结构我们知道普通函数有两个原型,一个是作为函数特有的prototype,原型另一个是作为对象使用的__proto__原型(在之前讲原型的文章中都提过)
let arrowFn = ()=>{}
console.dir(arrowFn)
我们打印箭头函数的结构看到,箭头函数没有prototype原型,所以我们知道了:
箭头函数没有自己的this
箭头函数因为没有prototype原型,所以也没有constructor构造函数,所以无法实例化对象
那在箭头函数中使用this,又有什么情况呢?
我们来定义一个对象
let obj = {name: 'lili',age: 18,getName(){return ()=>{ console.log(this.name) }},getAge: ()=>{ console.log(this.age) }
}var name = 'mike'
var age = 28
let getName = obj.getName()
getName() //lili
obj.getAge() //28
我们在上面定义了一个对象obj,然后在里面我们给它添加了两个属性getName和getAge,可以看到两种形式,一种是箭头函数外面套了一个普通函数,另外一个箭头函数直接添加到obj上面
由代码运行的结果,我看可以看到
箭头函数中的this指向父级作用域中的this,并且,如果箭头函数外层没有普通函数,那么它的this将指向window(全局对象)
我们在上面打印箭头函数的结构是看到,箭头函数也拥有call、apply、bind的属性,那能不能利用它们改变this的指向呢,来试试
let obj = {name: 'lili',age: 18,getName(){return (()=>{ console.log(this.name) }).bind(window)},getAge: ()=>{ console.log(this.age) }
}
let getName = obj.getName()
getName() //lili
可以看到,虽然箭头函数也有call、apply、bind的属性,但是箭头函数无法通过call、apply、bind改变this的指向,它的this永远指向父及作用域中的this
还是回头去看打印的箭头函数的结构,我们发现箭头函数也有arguments,现在我们来改造一下obj,打印arguments
let obj = {name: 'lili',age: 18,getName(param1, param2){return ()=>{ console.log(arguments)}},getAge: (param1, param2)=>{ console.log(arguments) }
}
我们先来看看this指向父及作用域的箭头函数中arguments
obj.getName()()
我们看到this指向父及作用域的箭头函数中arguments,也是继承了父级函数中的arguments
我们再来看this指向全局对象的情况
obj.getAge()。 // Uncaught ReferenceError: arguments is not defined
报错了,所以我们有了结论:
箭头函数的this指向全局,使用arguments会报未声明的错误。
箭头函数的this指向普通函数时,它的argumens继承于该普通函数