当前位置:网站首页>【面试题】1369- 什么时候不能使用箭头函数?
【面试题】1369- 什么时候不能使用箭头函数?
2022-07-03 01:02:00 【pingan8787】
箭头函数
箭头函数是和我们工作密切相关的东西;可以说箭头函数的诞生,给我们的工作带来了极大的便利。但是箭头函数有什么缺点?什么时候不能使用箭头函数? 这你了解吗?
我们觉得箭头函数很高级,可以规避 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
边栏推荐
- Asynchronous, email and scheduled tasks
- [system analyst's road] Chapter V double disk software engineering (development model development method)
- Explain the basic concepts and five attributes of RDD in detail
- MySQL basics 03 introduction to MySQL types
- 按键精灵打怪学习-前台和内网发送后台验证码
- 465. DFS backtracking of optimal bill balance
- 如今少年已归来,人间烟火气最抚凡人心 复工了~
- [C language] detailed explanation of pointer and array written test questions
- MySQL基础用法02
- MySQL - database query - condition query
猜你喜欢
leetcode:701. 二叉搜索树中的插入操作【bst的插入】
基本远程连接工具Xshell
[Androd] Gradle 使用技巧之模块依赖替换
How wide does the dual inline for bread board need?
[androd] module dependency replacement of gradle's usage skills
Daily topic: movement of haystack
Esp32 simple speed message test of ros2 (limit frequency)
【FH-GFSK】FH-GFSK信号分析与盲解调研究
Merge K sorted linked lists
JS inheritance and prototype chain
随机推荐
Strongly connected components of digraph
【FPGA教程案例6】基于vivado核的双口RAM设计与实现
leetcode:701. 二叉搜索树中的插入操作【bst的插入】
Matlab Doppler effect produces vibration signal and processing
Mongodb common commands of mongodb series
FPGA - 7 Series FPGA internal structure clocking -04- multi area clock
Tp6 fast installation uses mongodb to add, delete, modify and check
MySQL basics 03 introduction to MySQL types
机器学习术语
Asynchronous, email and scheduled tasks
一位苦逼程序员的找工作经历
Create your first Kivy program Hello word (tutorial includes source code)
Key wizard play strange learning - front desk and Intranet send background verification code
leetcode 6103 — 从树中删除边的最小分数
异步、邮件、定时三大任务
[C language] detailed explanation of pointer and array written test questions
每日一题之干草堆的移动
寻找标杆战友 | 百万级实时数据平台,终身免费使用
d. LDC build shared library
[system analyst's road] Chapter V double disk software engineering (development model development method)