3

什么时候不能使用箭头函数?

 2 years ago
source link: https://developer.51cto.com/article/713795.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

面试官——什么时候不能使用箭头函数?-51CTO.COM

面试官——什么时候不能使用箭头函数?
2022-07-12 10:12:37
我们觉得箭头函数很高级,可以规避 this 的问题,所有的场景下都是用箭头函数。在不能使用的场景下使用了,出现了问题,你还不知道是什么问题,那这不是瞎添乱吗!是不是。
f6575de681aa496359e54388e489275b5048fc.jpg

箭头函数是和我们工作密切相关的东西;可以说箭头函数的诞生,给我们的工作带来了极大的便利。但是箭头函数有什么缺点?什么时候不能使用箭头函数? 这你了解吗?

我们觉得箭头函数很高级,可以规避 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 公布答案!

a35852e390fb50b15e7647d75f6251e1a7e52f.jpg

如果答错了,也别灰心,毕竟网络有着35的延迟,影响着你的操作和思考,看完这篇文章,保证你就不会答错了!

箭头函数有什么缺点?

  1. 没有 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)
44925d0240ef18a1d01915d7ecf96265ee4540.jpg
  1. 无法通过 apply、call、bind 改变this指向 这里我们在定义一个箭头函数和一个普通函数。
const fn3 = () => {
  console.log('this', this)
}
fn3()

function fn4(){
   console.log('this', this)
}
fn4()

箭头函数的this就是他父容器的this,不是在执行的时候确定的,而是在定义的时候确定的。

735a3093957042003af975047ed03623b7fb0a.jpg

如上图,我们可以发现,箭头函数的两次执行的 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输出什么?

公布答案:

99c040061385c00e882341692ad6d4cd7e3e10.jpg

我们发现箭头函数好像并没有获取到值诶!

为什么对象方法中,箭头函数的this指向不是这个对象?

  1. this 永远指向函数的调用者
  2. 在箭头函数中,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 公布答案:

e237c385624074b26a120144f78e2b6abd0c89.jpg

为什么?

出现问题的原因是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('张三', '男'))

不仅不行,还报错了呢!

b6ce108267c88cb1f002696c0d38a2ee1c8b1b.jpg

为什么?

  • 构造函数是通过 new 关键字来生成对象实例,生成对象实例的过程也是通过构造函数给实例绑定 this 的过程,而箭头函数没有自己的 this。因此不能使用箭头作为构造函数,也就不能通过 new 操作符来调用箭头函数。

4. 动态上下文中的回调函数

比如,我们需要给一个按钮添加点击事件:

const btn1 = document.getElementById('btn1')
btn1.addEventListener('click', () => {
   this.innerHTML = 'clicked'
})

如果我们在回调中不需要使用到 this,那就啥问题也没有,但是!使用到了 this,那么问题就大大的了!

为什么呢?

箭头函数的 this 指向的是他的父作用域(这里就指向了 window),而不是指向这个button。这时候我们需要使用普通函数才可以。

5. Vue 生命周期和 method 中也不能使用箭头函数

29341ee257d2730867d642ab3bb26670c789a2.jpg

为什么不行呢?

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())
03358c947b2e99470f57612e8656c422718665.jpg
  • 要熟练使用箭头函数,也要对函数 this(重点) 敏感。
  • Vue组件本质上是一个 JS 对象;React 组件(非Hooks)他本质上是一个 ES6 的 class,两者不同。

Recommend

  • 21
    • 掘金 juejin.im 6 years ago
    • Cache

    ES6 系列之箭头函数

    回顾 我们先来回顾下箭头函数的基本语法。 ES6 增加了箭头函数: let func = value => value; 相当于: let func = function (value) { return value; }; 如果需要给函数传入多

  • 45

    现代 JavaScript 中最引人注目的功能之一是引入了箭头函数,用 => 来标识。

  • 35

    原文作者:Karthik Kalyanaraman译者:Sangle译者的话:JS 类中的箭头函数只是语法糖,在编译之后,它将出现在构造函数中,在实例化时创建并分配,这就是为什么我们没有在原型中看到这些方法。在使用箭头函数(而…

  • 39

    2020年02月14日 阅读 2378 编写高质量箭头函数的5个最佳做法 作者:Dmitri Pavlutin 译者:前...

  • 38
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    箭头函数和常规函数之间的 5 个区别

    每日前端夜话 第339篇 翻译: 疯狂的技术宅 作者:Dmitri Pavlutin 来源:dmitripavlutin 正文共:2899  字

  • 5
    • my.oschina.net 3 years ago
    • Cache

    ES6 箭头函数你正确使用了吗

    ES6 箭头函数你正确使用了吗 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 在ES6中允许使用“箭头”...

  • 7
    • www.v2ex.com 3 years ago
    • Cache

    js this 绑定和箭头函数定义

    定义:箭头函数相当于匿名函数,并且简化了函数定义 如:x => x * x 1.箭头函数看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的 this 是词法作用域,由上下文确定。 2.箭头...

  • 9
    • foofish.net 3 years ago
    • Cache

    javascript 箭头函数介绍

    javascript 箭头函数介绍箭头函数是ES6中出现的一种定义函数的简写方法, 用=>分隔参数列表和函数体。 let square = x=>x**2; console.log(square(3)) 9 这个函数的定义等价于...

  • 6

    对象方法中,不适用箭头函数下面看一个例子:const obj = { name: '张三', getName() { return this.name }, getName1: () => { return this...

  • 6
    • www.myfreax.com 1 year ago
    • Cache

    什么时候不该使用箭头函数

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK