面试题之箭头函数和普通函数有什么区别?

箭头函数(Arrow Function)和普通函数(Regular Function)是 JavaScript 中两种不同的函数定义方式,它们在语法、上下文(this)、原型链等方面存在显著区别。以下是它们的主要区别:


1. 语法差异

  • 普通函数:

    function normalFunction(a, b) {return a + b;
    }

    或者使用函数表达式:

    const normalFunction = function(a, b) {return a + b;
    };
  • 箭头函数:

    const arrowFunction = (a, b) => {return a + b;
    };

    如果箭头函数体只有一条语句,可以省略大括号并自动返回结果:

    const arrowFunction = (a, b) => a + b;

2. this 的处理方式

这是箭头函数和普通函数最重要的区别之一。

  • 普通函数:

    • 普通函数的 this 是动态绑定的,取决于函数的调用方式:

      • 作为方法调用: this 指向调用它的对象。

        const obj = {
            name: "Kimi",
            greet: function() {
                console.log(this.name); // 输出 "Kimi"
            }
        };
        obj.greet();

      • 作为普通函数调用: this 指向全局对象(非严格模式下是 windowglobal,严格模式下是 undefined)。


        function greet() {
            console.log(this);
        }
        greet(); // 非严格模式下输出 window,严格模式下输出 undefined

      • 使用 callapplybind: 可以手动绑定 this

        greet.call({ name: "Kimi" }); // 输出 { name: "Kimi" }
  • 箭头函数:

    • 箭头函数没有自己的 this,它会捕获其所在上下文的 this 值,并在函数内部使用。

    • 箭头函数的 this 是在定义时就确定的,不会随着调用方式改变。

    const obj = {
        name: "Kimi",
        greet: () => {
            console.log(this.name); // 输出 undefined(因为箭头函数捕获了全局上下文的 this)
        }
    };
    obj.greet();

    const normalGreet = function() {
        console.log(this.name); // 输出 "Kimi"
    };
    const arrowGreet = () => {
        console.log(this.name); // 输出 undefined
    };

    normalGreet.call({ name: "Kimi" }); // 输出 "Kimi"
    arrowGreet.call({ name: "Kimi" }); // 输出 undefined


3. arguments 对象

  • 普通函数:

    • 普通函数内部可以访问 arguments 对象,它是一个类数组对象,包含函数调用时传入的所有参数。

    function sum() {
        console.log(arguments); // 类数组对象,包含所有参数
        return Array.from(arguments).reduce((a, b) => a + b, 0);
    }
    console.log(sum(1, 2, 3)); // 输出 6

  • 箭头函数:

    • 箭头函数不绑定自己的 arguments 对象,只能通过参数名访问参数。

    const sum = (...args) => {
        console.log(arguments);  // ReferenceError: arguments is not defined
        return args.reduce((a, b) => a + b, 0);
    };
    console.log(sum(1, 2, 3)); // 输出 6


4. new 调用

  • 普通函数:

    • 普通函数可以用 new 关键字创建一个新的实例对象。

    function Person(name) {
        this.name = name;
    }
    const person = new Person("Kimi");
    console.log(person); // 输出 { name: "Kimi" }

  • 箭头函数:

    • 箭头函数不能用 new 关键字调用,否则会抛出错误。

    const Person = (name) => {
        this.name = name;
    };
    const person = new Person("Kimi"); // TypeError: Person is not a constructor


5. 原型链

  • 普通函数:

    • 普通函数有 prototype 属性,可以用于原型链继承。

    function Person(name) {
        this.name = name;
    }
    Person.prototype.greet = function() {
        console.log(`Hello, my name is ${this.name}`);
    };
    const person = new Person("Kimi");
    person.greet(); // 输出 "Hello, my name is Kimi"

  • 箭头函数:

    • 箭头函数没有 prototype 属性,因此不能用于原型链继承。

    const Person = (name) => {
        this.name = name;
    };
    console.log(Person.prototype); // undefined


6. 使用场景

  • 普通函数:

    • 适用于需要动态绑定 this 的场景,例如作为方法调用、事件处理器、构造函数等。

    • 适用于需要访问 arguments 对象的场景。

  • 箭头函数:

    • 适用于不需要动态绑定 this 的场景,例如回调函数、匿名函数等。

    • 适用于需要简洁语法的场景,尤其是只有一条语句时。


总结

  • 普通函数:

    • 有自己的 this,动态绑定。

    • arguments 对象。

    • 可以用 new 调用。

    • prototype 属性。

    • 语法稍显复杂。

  • 箭头函数:

    • 没有自己的 this,捕获定义时的上下文。

    • 没有 arguments 对象。

    • 不能用 new 调用。

    • 没有 prototype 属性。

    • 语法简洁。

根据实际需求选择合适的函数类型可以提高代码的可读性和效率。

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

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

相关文章

Llama 3.1 本地电脑部署 Linux系统 【轻松简易】

本文分享在自己的本地电脑部署 llama3.1,而且轻松简易,快速上手。 这里借助Ollama工具,在Linux系统中进行大模型部署~ Llama3.1,有三个版本:8B、70B、405B Llama 3.1 405B 是第一个公开可用的模型,在常识…

工业安全的智能哨兵:AI如何筑起生产线的“数字防火墙“

工业安全的智能哨兵:AI如何筑起生产线的"数字防火墙" (本文共1420字,阅读约需4分钟) 去年某石化厂的反应釜压力数据出现异常波动,传统监测系统在15分钟后才发出警报——而AI模型在23秒前就已预警。这场未遂事故揭示了一个残酷现实:工业安全监测正在经历从&qu…

【Bert】自然语言(Language Model)入门之---Bert

every blog every motto: Although the world is full of suffering, it is full also of the overcoming of it 0. 前言 对bert进行梳理 论文: BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 时间:…

Linux中使用Docker安装DIFY搭建本地支持库和Agent

Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者可以快速搭建生产级的生成式 AI 应用。即使你是非技术人员,也能参与到 AI 应用的定义和数据运营过程中。 然而…

开源工具推荐--思维导图、流程图等绘制

1. 前言 在工作中,经常要用到各种不同的工具,随着系统的升级,有些工具也在不断更新升级。这里收集整理一些好用的开源工具推荐,遵循以下一些基本原则:开源免费,商业工具的有效平替,轻量级&…

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_create_pool函数

ngx_create_pool 声明在 src\core\ngx_palloc.h 中 ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log); 实现在 src\core\ngx_palloc.c 中 ngx_pool_t * ngx_create_pool(size_t size, ngx_log_t *log) {ngx_pool_t *p;p ngx_memalign(NGX_POOL_ALIGNMENT, size, lo…

ac的dhcp池里option43配错导致ap无法上线问题排查过程

dhcp池里ac地址配错,导致ap无法上线问题排查过程 问题:ap手动设置ac的ip正常注册在线,但dhcp获得ip和ac地址发现无法在ac上注册成功。 组网: ac旁路结构,路由器lan口地址172.16.1.1,开dhcp服务&#xff0…

IntelliJ IDEA中Maven配置全指南

一、环境准备与基础配置 1.1 Windows 环境下载并配置 Maven 见此篇博文:环境配置 1.2 IDEA配置步骤 打开设置面板:File → Settings → Build → Build Tools → Maven 关键配置项: Maven home path E:\apache-maven-3.9.9 (…

存储区域网络(SAN)管理

存储区域网络(Storage Area Network,SAN)采用网状通道(Fibre Channel ,简称FC)技术,通过FC交换机连接存储阵列和服务器主机,建立专用于数据存储的区域网络。SAN提供了一种与现有LAN连…

使用vue-office报错TypeError: ft.createElementVNode is not a function

支持多种文件(.docx、.xlsx、.xls、.pdf、.pptx)预览的vue组件库,支持vue2/3。也支持非Vue框架的预览。 不支持.doc、.ppt(2003年及以前的版本) 官网:https://www.npmjs.com/package/vue-office/excel?activeTabreadme 官方有实…

Ubuntu部署ktransformers

准备工作 一台服务器 CPU:500G GPU:48G(NVIDIA4090) 系统:Ubuntu20.04(github的文档好像用的是22.04) 第一步:下载权重文件 1.下载hfd wget https://hf-mirror.com/hfd/hfd.s…

C++初阶——简单实现vector

目录 1、前言 2、Vector.h 3、Test.cpp 1、前言 简单实现std::vector类模板。 相较于前面的string,vector要注意: 深拷贝,因为vector的元素可能是类类型,类类型元素可以通过赋值重载,自己实现深拷贝。 迭代器失效…

全志A133 android10 适配SLM770A 4G模块

一,模块基本信息 1.官方介绍 SLM770A是美格智能最新推出的一款LTE Cat.4无线通讯模组,最大支持下行速率150Mbps及上行速率50Mbps。同时向下兼容现有的3G和2G网络,以确保即使在偏远地区也可以进行网络通信。 SLM770A模组支持分集接收和MIMO技…

微信小程序:多菜单栏设计效果

一、实现效果 二、代码 wxml 编辑前端界面,步骤 菜单逻辑: 逐步取出数组中的项,首先取出顶部菜单项,然后选中后取出选中的底部数据(左侧菜单+右侧内容),然后点击左侧菜单取出选中的左侧菜单对应的右侧内容 ①这里我的数据是全部封装到一个数组对象的,首先我的循环…

C++基础知识学习记录—string类

string实际上是C内置的一个类,内部对char *进行了封装,不用担心数组越界问题,string类中,除了上课讲解的函数外,还有很多函数可以使用,可以自行查阅文档。 构造函数原型: string(); //创建一个…

Ollama+DeepSeek+Open-WebUi

环境准备 Docker Ollama Open-WebUi Ollama 下载地址:Ollama docker安装ollama docker run -d \ -v /data/ollama/data:/root/.ollama \ -p 11434:11434 \ --name ollama ollama/ollama 下载模型 Ollama模型仓库 # 示例:安装deepseek-r1:7b doc…

设计模式--访问者模式【行为型模式】

设计模式的分类 我们都知道有 23 种设计模式,这 23 种设计模式可分为如下三类: 创建型模式(5 种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。结构型模式(7 种)&#xff1…

前端循环全解析:JS/ES/TS 循环写法与实战示例

循环是编程中控制流程的核心工具。本文将详细介绍 JavaScript、ES6 及 TypeScript 中各种循环的写法、特性,并通过实际示例帮助你掌握它们的正确使用姿势。 目录 传统三剑客 for 循环 while 循环 do...while 循环 ES6 新特性 forEach for...of for...in 数组…

数据中心储能蓄电池状态监测管理系统 组成架构介绍

安科瑞刘鸿鹏 摘要 随着数据中心对供电可靠性要求的提高,蓄电池储能系统成为关键的后备电源。本文探讨了蓄电池监测系统在数据中心储能系统中的重要性,分析了ABAT系列蓄电池在线监测系统的功能、技术特点及其应用优势。通过蓄电池监测系统的实施&#…

Mac端homebrew安装配置

拷打了一下午o3-mini-high,不如这位博主的超强帖子,10分钟结束战斗 跟随该文章即可,2025/2/19亲测可行 mac 安装HomeBrew(100%成功)_mac安装homebrew-CSDN博客文章浏览阅读10w次,点赞258次,收藏837次。一直觉得自己写…