js箭头函数和普通函数区别

js箭头函数和普通函数区别

实验环境:nodejs v12.16.1

  1. 箭头函数不能作为构造函数,而普通函数可以 在这里插入图片描述

  2. 箭头函数没有原型,而普通函数有
    在这里插入图片描述

  3. 箭头函数return可以省略语句块。(如果=>右边不是语句块,则代表return右边的表达式或对象)
    在这里插入图片描述

  4. 箭头函数不绑定arguments(注意:浏览器环境下获取箭头函数的arguments会报错),而普通函数argument绑定了参数列表对象
    在这里插入图片描述

  5. this指向问题[重点,也是难点]

    • 箭头函数的this指向上层函数作用域的this对象,如果没有上层函数作用域,则指向顶部this(在浏览器中顶部this则是window)。普通函数的this指向该函数的调用者
    • call, apply, bind会改变普通函数的this,但不会改变箭头函数的this
      在这里插入图片描述
      实践是检验真理的有效标准,在此,我们必须更加深入了解,再耐心看一个复杂的例子:
      依然是nodejs环境下:
    data = 40; // 全局作用域赋予data=40
    this.data = 30; // 给顶部this赋予data=30
    let pig = {data: 80,
    };
    let o = {data: 10,a(n) {let f = (n) => {// 分析如下:// 首先f是箭头函数,那么f的this指向上层函数作用域的this,f的上层函数作用域是a,因此f的this指向a的this// 由于a是普通函数,因此a的this指向a的调用方// 因此f的this指向a的调用方return n + this.data;};return f(n);},b(n) {let f = (n) => {return n + this.data;};let other = {data: 20,};// 分析如下:// 和函数a的情形分析一样,这里的f的this指向是b的调用方// 然而 call,bind,apply 并不会改变箭头函数的调用方,因此f.call(other, n)并不会把this指向otherreturn f.call(other, n);},c(n) {let f = function (n) {// 分析如下:// f是普通函数,因此f的this指向f的调用方return n + this.data;};let other = {data: 20,};// 分析如下:// call会改变普通函数的调用方,因此f.call(other, n)把this指向了otherreturn f.call(other, n);},d: (n) => {let f = (n) => {// 分析如下:// f是箭头函数,因此f的this指向上层函数作用域d的this// 由于d也是箭头函数,由于d没有再上层的函数作用域了,因此d的this指向顶部this// 因此f的this指向顶部thisreturn n + this.data;};return f(n);},e(n) {let f = function (n) {return n + this.data;};let other = {data: 20,};// g的this指向other了let g = f.bind(other);return g(n);},e1(n) {let f = function (n) {return n + this.data;};// 注意,nodejs下这里f的调用方是global(注意nodejs下的顶层this并不等于global,顶层this是当前模块的this)return f(n);},e2(n) {let f = (n) => {return n + this.data;};let other = {data: 20,};// bind对箭头函数不起作用,f的this -> e2的this -> e2的调用方let g = f.bind(other);return g(n);},
    };console.log(o.a(1)); // 11
    console.log(o.b(1)); // 11
    console.log(o.c(1)); // 21
    console.log(o.d(1)); // 31
    console.log(o.e(1)); // 21
    console.log(o.e1(1)); // 41
    console.log(o.e2(1)); // 11console.log(`============接下来比较复杂,但是要搞清楚=========================`);// 分析:
    // o.a普通函数,因此bind把o.a的this指向pig
    // o.a里面的f的this指向o.a的调用方,因此f的this指向pig
    console.log(o.a.call(pig, 1)); // 81console.log(o.b.call(pig, 1)); // 81console.log(o.c.call(pig, 1)); // 21console.log(o.d.call(pig, 1)); // 31console.log(o.e.call(pig, 1)); // 21console.log(o.e1.call(pig, 1)); // 41// 分析
    // o.e2普通函数,因此bind把o.e2的this指向pig
    // o.e2里面的f是箭头函数,因此f指向上层函数作用域o.e2的this,而o.e2的this指向了pig,因此f的this指向pig
    // o.e2里面的f是箭头函数,不会被bind改变指向,因此g的this也指向pig
    console.log(o.e2.call(pig, 1)); // 81
    
  6. 箭头函数内不能用yield且不能用作Generator函数,而普通函数可以。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git 更新_[技术分享T.191212]GitLab使用方法及git命令常见问题(不断更新)

该文章用于记录一些GitLab的使用指南,以及在实际版本控制过程中遇到的问题及解决方法,会尽量及时的更新~GitLab简介:GitLab和GitHub很相似都属于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来…

记一次开发实战-对提供接口的C/C++进行二次开发

点击蓝字关注我们一、需求描述我有一个USB5538的库和头文件,并通过头文件提供了接口,我想把它更改一下,编译成python可调用的模块。二、创建工程及其目录1、创建空项目2、创建目录三、创建文件1、复制文件并添加2、添加新文件并写入四、环境配…

C++是如何实现多态的

C是如何实现多态的结论:C通过虚函数来实现多态的,根本原因是派生类和基类的虚函数表的不同。 构成多态的必要条件有如下3点: 存在继承关系基类存在虚函数,且派生类有相同原型的函数遮蔽它存在基类类型的指针指向派生类对象&…

C语言实现通讯录附详细代码(动态+静态)

点击蓝字关注我们一、通讯录简介实现一个通讯录;通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址提供方法:添加联系人信息删除指定联系人信息查找指定联系人信息修改指定联系人信息显示所有联系…

Lua协程Coroutine是什么

Lua协程Coroutine是什么协程和线程不同: 同一时刻,一个多线程程序可以用多个线程同时执行;而协程只能有一个在执行多线程是抢占式的;而协程是非抢占式的,只有协程显示被挂起,才会被挂起 协程和线程的相同…

C++程序的内存分区模型-栈区堆区

点击蓝字关注我们1、栈区:由编译器自动分配释放,存放函数的参数值,局部变量等(由编译器管理其“生死”)注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放栈区代码演示&#xff…

CocosStudio的节点如何使用自定义shader

CocosStudio的节点如何使用自定义shader问题:我想对CocosStudio 的 某个UI 里的 某个图片(如下图所示的Image类型)使用自定义shader。但是,我把 对传统的cc.Sprite应用自定义shader的方式 应用于它时,并不生效&#xf…

excel随机抽取_简单随机抽样及其进阶分层随机抽样方法展示

一、分享简单随机抽样的几种方法1、抽样分析工具抽样2、INDIRECTRANDBETWEEN函数抽样3、RAND排序抽样4、SAS抽样二、分层抽样方法1、Python分层抽样2、SAS分层抽样3、EXCEL函数及功能分层抽样简单随机抽样的几种方法方法一抽样分析工具抽样如果你的EXCEL尚未安装数据分析&#…

为什么存在动态内存分配,动态内存函数(malloc函数,free函数,calloc函数,realloc函数)...

点击蓝字关注我们1.当前我们知道的内存的使用方法2.为什么存在动态内存分配如上我们已学的开辟空间的方式有两个特点:空间开辟的大小是固定的必须指定数组的长度所以就产生了空间开大了浪费开小了不够用的问题,所以使用动态内存分配3.动态内存函数&#…

C++ vector类的模拟实现

点击蓝字关注我们1.前言vector和string虽然底层都是通过顺序表来实现的,但是他们利用顺序表的方式不同,string是指定好了类型,通过使用顺序表来存储并对数据进行操作,而vector是利用了C中的泛型模板,可以存储任何类型的…

visual studio源文件的编译顺序是依据什么?

问题:visual studio源文件的编译顺序是依据什么? 结论:依据 .vcxproj 文件里 指定了ClCompile的ItemGroup ,如下图所示,就是这么简单粗暴。

功能齐全的屏幕截图C++实现详解

点击蓝字关注我们1、概述要使用屏幕截图,其实很容易,装一款聊天软件或者办公软件就可以了,比如QQ、企业微信、钉钉、飞书等。但要开发出类似这些软件的屏幕截图模块,则没那么容易。其实实现屏幕截图的技术并不复杂,主要…

如何判断exe文件是debug还是release编译生成的

如何判断exe文件是debug还是release编译生成的结论: 用IDA工具打开exe,然后看Imports里面的依赖库是否有带d或D结尾的,如果有就说明是Debug的 实验:(实验环境 vs2017, IDA工具) (0&…

大屏可视化分配率是什么意思_什么是分配率?

大屏可视化分配率是什么意思诸如“不可持续的分配率”和“您需要保持较低的分配率”之类的短语似乎仅属于Java Champions的词汇表。 复杂,恐怖并被魔术光环包围。 经常发生的情况是,当您更仔细地查看概念时,魔术会随着抽烟消失。 这篇文章试…

C/C++语言动态开辟的杨辉三角

点击蓝字关注我们问题引入杨辉三角相必大家并不陌生,第1行有1列、第二行有2列…第n行有n列,且每行行首和行尾的值都为1,其余的值为上一行两数相加我们在C语言阶段,第一次碰到的杨辉三角应该都是用常规的二维数组存储,可…

git gui 历史版本_这些Git命令都不会,还是不要去面试了

前言以下,项目中经常使用的Git命令,汇总到这里以便与你能快速的学习和掌握Git命令,在文章最后有惊喜哟,一定要看到最后啊!使用的 Git版本:git version 2.24.0命令git log# 输出概要日志,这条命令等同于# gi…

java restful_Java EE中的RESTful计时器

java restful在这篇文章中...。 EJB计时器旋风之旅 通过带有示例实现的简单REST接口即时使用EJB计时器 更新(2015年7月14日) 该应用程序的前端现在可以在OpenShift上使用 。 由于我是前端新手,因此我在其他来源的帮助下组装了此HTML5 Ang…

c# 联合halcon 基于相关性 模板匹配_机器视觉之halcon入门(5)-字符识别exe生成...

2.3.2 第二个halcon程序转EXE程序:字符识别老规矩,每一段halcon代码得用C#二次开发下。根据上一节所教的,我们配置下C#的环境,顺便添加好控件,如下图(2-3-2-1)。图 2-3-2-1控件基本跟上一节一样,只是少了一…

C语言数据的存储和取出(超详细讲解)

点击蓝字关注我们整形的储存我们知道一个整形的存储是以补码的形式储存取出是原码的形式。比如:int a 5;的二进制是101那它的原码应该是:00000000 00000000 00000000 00000101正数的原反补相同那它存进去和取出来都是:00000000 00000000 000…

打印pdf就一页_PDF 文件转换工具

是将 PDF 文件转换为完全可编辑的 Windows 文档最好的转换软件。无论您需要您的内容是 Microsoft Word、Excel、PowerPoint、HTML 还是仅需要文本, 总会给您一个简单的方法,快捷地获取您要的内容。可转换整个文档或选择内容。亦可创建 PDF 文件。PDF 转换…