const obj = {
name: '张三',
getName() {
return this.name
},
getName1: () => {
return this.name
}
}
obj.__proto__.getName2 = function() {
return this.name
}
obj.__proto__.getName3 = () => {
return this.name
}
console.log('普通函数',obj.getName())
console.log('普通函数',obj.getName2())
console.log('箭头函数',obj.getName1())
console.log('箭头函数',obj.getName3())
在上述例子中 函数getName、getName2为普通函数 getName1 getName3为箭头函数
输出结果为:
上述例子中箭头函数都没有输出值 这就引申出了一个问题
什么时候不能使用箭头函数
1.对象方法中,不适用箭头函数
上述例子中 getName是对象方法中的普通函数,结果输出了 张三、 getName1就是对象方法中的箭头函数,结果未输出
为什么对象方法中,箭头函数的this指向的不是这个对象
- this的指向永远是谁调用指向谁
- 在箭头函数中,this指向的是定义时所在的对象,而不是使用时所在的对象,也就是说 箭头函数没有自己的this,它继承的是父作用域中的this
obj.getName()中的this指向的是它的调用者 obj 因此this.name等价于obj.name 结果为 张三
getName1() 是箭头函数 没有自己的this 继承父作用域的this 父作用域是window 因此obj.getName1() 中的this.name 等价于 window.name 因此得不到结果
因此, 对象中定义的函数使用箭头函数是不合适的
2.原型方法中,不适用箭头函数
上述例子中getName2是原型方法中的普通函数,结果输出了张三,getName3是原型方法中的箭头函数,结果未输出
原因:getName3()是箭头函数 this指向window对象。
3.构造函数,不适用箭头函数
function Foo (name,sex) {
this.name = name;
this.sex = sex;
}
const Foo1 = (name,sex) => {
this.name = name;
this.sex = sex;
}
console.log('普通的构造函数', new Foo('张三','男'));
console.log('箭头函数', new Foo1('张三','男'));
上述例子中Foo1箭头函数报错
原因:构造函数是通过new关键字来生成对象实例,生成对象实例的过程也是通过构造函数给实例绑定this的过程,而箭头函数没有自己的this。因此不能使用箭头函数作为构造函数,也就不能通过new操作符来调用箭头函数。
4.动态上下文中的回调函数
const btn = document.getElementById('btn');
btn.addEventListener('click', () => {
this.innerHTML = 'clicked';
})
在回调中不需要使用到this,是不会有问题的,但是使用到this,就是不行,因为箭头函数的this指向的是它的父作用域(这里就是指向window),而不是指向这个btn。这时候需要使用普通函数才可以。
5.Vue生命周期和method中也不能使用箭头函数
export default {
name: "",
data: function() {
return {
name: '张三',
};
},
methods: {
getName: () => {
return this.name //报错
},
getName () {
return this.name //正常
},
},
mounted: () => {
console.log('msg',this.name) //报错
},
mounted () => {
console.log('msg',this.name) //正常
}
};
原因:Vue本质上是一个JS对象,对象方法中,不适用箭头函数。
react框架是可以使用构造函数的
原因:React组件(非Hooks)他本质上是一个ES6的class
class Man {
constructor(name,sex) {
this.name = name
this.sex = sex
}
getName = () => {
return this.name
}
}
const f = new Man('张三','男')
console.log(f.getName())
要熟练使用箭头函数,也要对函数this(重点)敏感
Vue组件本质上是一个JS对象;React组件(非Hooks)他本质上是一个ES6的class,两者不同
箭头函数的缺点
1.没有arguments,如果要用,可以用rest参数代替
const fn1 = () => {
console.log('arguments',arguments)
}
fn1(100,200)
function fn2(){
console.log('arguments',arguments)
}
fn2(100,200)
const fn3 = (...values) => {
console.log('values',values)
}
fn3(100,200)
2.无法通过apply、call、bind改变this指向
const fn3 = () => {
console.log('this',this)
}
fn3()
function fn4(){
console.log('this',this)
}
fn4()
fn3.call()不会改变
如上图,可以看到,箭头函数两次执行的this都是指向了window,使用call并没有发生改变,而普通函数第一次指向了window,第二次则是变成了我们传入的
这是因为箭头函数的this就是他父容器的this,不是在执行的时候确定的,而是在定义的时候确定的