当前位置:网站首页>在什么场景下,我们不能使用箭头函数?
在什么场景下,我们不能使用箭头函数?
2022-06-10 14:47:00 【前端达人】

箭头函数
箭头函数是和我们工作密切相关的东西;可以说箭头函数的诞生,给我们的工作带来了极大的便利。但是箭头函数有什么缺点?什么时候不能使用箭头函数? 这你了解吗?
我们觉得箭头函数很高级,可以规避 this 的问题,所有的场景下都是用箭头函数。在不能使用的场景下使用了,出现了问题,你还不知道是什么问题,那这不是瞎添乱吗!是不是!
这里给大家先提出一个问题:
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())
复制代码大家觉得会输出什么呢?
先悄悄思考一下!
3,2,1 公布答案!

如果答错了,也别灰心,毕竟网络有着35的延迟,影响着你的操作和思考,看完这篇文章,保证你就不会答错了!
箭头函数有什么缺点?
没有 arguments,如果要用,可以用 rest 参数代替。这里我们定义一个箭头函数和一个普通函数还有一个使用 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) 复制代码
image.png 无法通过 apply、call、bind 改变this指向 这里我们在定义一个箭头函数和一个普通函数
const fn3 = () => { console.log('this', this) } fn3() function fn4(){ console.log('this', this) } fn4() 复制代码箭头函数的this就是他父容器的this,不是在执行的时候确定的,而是在定义的时候确定的。
如上图,我们可以发现,箭头函数的两次执行的 this 都是指向了 Windows,使用call并没有发生改变,而普通函数第一次是指向了Windows,第二次则是变成了我们传入的
什么时候不能使用箭头函数?
1. 对象方法中,不适用箭头函数
const obj = {
name: '张三',
getName() {
return this.name
},
getName1: () => {
return this.name
}
}
复制代码我们在对象中定义了普通函数:getName和箭头函数 getName1,接下来我们来调用一下:
console.log('普通函数',obj.getName())
console.log('箭头函数',obj.getName1())
复制代码这里给大家默想3s输出什么?
公布答案:
我们发现箭头函数好像并没有获取到值诶!
为什么对象方法中,箭头函数的this指向不是这个对象?
this 永远指向函数的调用者
在箭头函数中,this 指向的是定义时所在的对象,而不是使用时所在的对象。换句话说,箭头函数没有自己的 this,而是继承父作用域中的 this。
obj.getName()中this指向函数的调用者,也就是obj实例,因此this.name = "张三"。
getName1()通过箭头函数定义,而箭头函数是没有自己的this,会继承父作用域的this。
因此obj.getName1()执行时,此时的作用域指向window,而window没有定义age属性,所有报空。
从例子可以得出:对象中定义的函数使用箭头函数是不合适的。
2. 原型方法中,不适用箭头函数
const obj = {
name: '张三',
}
obj.__proto__.getName = function() {
return this.name
}
obj.__proto__.getName1 = () => {
return this.name
}
复制代码我们又又又在对象中定义了普通函数:getName和箭头函数 getName1,接下来我们来调用一下:
console.log(obj.getName())
console.log(obj.getName1())
复制代码这里再再再给大家默想3s输出什么?
bang bang bang 公布答案:
为什么?
出现问题的原因是this指向window对象,这和使用箭头函数在对象中定义方法十分类似。
3. 构造函数也不行!
我们又又又定义了普通的构造函数:Foo和箭头函数 Foo1,接下来我们来调用一下:
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('张三', '男'))
复制代码不仅不行,还报错了呢!
为什么?
构造函数是通过 new 关键字来生成对象实例,生成对象实例的过程也是通过构造函数给实例绑定 this 的过程,而箭头函数没有自己的 this。因此不能使用箭头作为构造函数,也就不能通过 new 操作符来调用箭头函数。
4. 动态上下文中的回调函数
比如,我们需要给一个按钮添加点击事件:
const btn1 = document.getElementById('btn1')
btn1.addEventListener('click', () => {
this.innerHTML = 'clicked'
})
复制代码如果我们在回调中不需要使用到 this,那就啥问题也没有,但是!使用到了 this,那么问题就大大的了!
为什么呢?
箭头函数的 this 指向的是他的父作用域(这里就指向了 window),而不是指向这个button。这时候我们需要使用普通函数才可以。
5. Vue 生命周期和 method 中也不能使用箭头函数

为什么不行呢?
Vue 本质上是一个对象,我们说过对象方法中,不适用箭头函数。他的本质上的和对象方法中,不适用箭头函数是一样的。
那么我有一个问题:Vue不行,作为大热框架之一的 react 行吗?
回答是:react 行
因为 Vue组件本质上是一个 JS 对象;React 组件(非Hooks)他本质上是一个 ES6 的 class
不信的话我们测试一下就知道了
class Man {
constructor(name, city) {
this.name = name
this.city = city
}
getName = () => {
return this.name
}
}
const f = new Man('李四','上海')
console.log(f.getName())
复制代码
划重点
要熟练使用箭头函数,也要对函数 this(重点) 敏感
Vue组件本质上是一个 JS 对象;React 组件(非Hooks)他本质上是一个 ES6 的 class,两者不同
The end
关于本文:
来源:是洋柿子啊
https://juejin.cn/post/7103702621369663518
边栏推荐
- Flutter learning personal summary 1
- 【原创】POI 5.x XSSF和HSSF使用自定义字体颜色
- 博主自白
- 100003字,带你解密 双11、618电商大促场景下的系统架构体系
- 这个牛逼的低代码生成器,现在开源了!
- 我的第一个Go程序
- 自推荐-深入理解RUST标准库内核
- [Chongqing University] information sharing of preliminary and second examinations (with postgraduate entrance examination group)
- 几种方式可以实现 JMeter 参数化?
- 超强实操!手把手教学Kinect深度图与RGB摄像头的标定与配准
猜你喜欢

Orgin framework notes
![[discrete mathematics review series] i. propositional logic](/img/ae/7f062cfa416a26be3d32dfb1353c80.png)
[discrete mathematics review series] i. propositional logic

作为程序员,对于底层原理真的有那么重要吗?

JMeter 中如何实现接口之间的关联?

Flutter drawer learning summary 6

orgin框架 笔记

小程序网络请求Promise化

KaTeX问题 —— csdn编辑时中打出等号对齐的样式

How to implement the association between interfaces in JMeter?

How can JMeter parameterization be implemented?
随机推荐
【离散数学期复习系列】四、图
CG碰撞检测 Collision Testing
Golang Beep包 播放mp3 无法获取总长度 streamer.Len()为0 其他格式却可以
My first go program
佳博GP2120TU标签打印机 安装和使用教程(PC)
Notes on the second test of C language
竟然还有人说ArrayList是2倍扩容,今天带你手撕ArrayList源码
二分查找详解
CVPR 2022 oral | SCI: fast, flexible and robust low light image enhancement
This awesome low code generator is now open source!
【奖励公示】【内容共创】第16期 五月絮升华,共创好时光!签约华为云小编,还可赢高达500元礼包!
orgin框架 笔记
Collision detection unity experiment code
QT 基于QScrollArea的界面嵌套移动
Flutter listview, column, row learning personal summary 2
碰撞检测 Unity实验代码
小程序网络请求Promise化
At the early stage of product development, do you choose to develop apps or applets?
[discrete mathematics review series] II. First order logic (predicate logic)
svn外网打不开url地址怎么解决