javascript中call、apply 和 bind 的区别详解

文章目录

  • 深入浅出:JavaScript 中的 call、apply 和 bind
    • 一、三位魔法师的共同使命
    • 二、各显神通的魔法师们
      • 1. call - 即时通讯专家
      • 2. apply - 批量处理高手
      • 3. bind - 预约服务大师
    • 三、魔法师们的对比表格
    • 四、魔法师们的实际应用
      • 1. 借用方法
      • 2. 函数柯里化
      • 3. 事件处理
    • 五、注意事项
    • 六、现代JavaScript的替代方案
    • 结语

在这里插入图片描述

深入浅出:JavaScript 中的 call、apply 和 bind

在 JavaScript 的世界里,callapplybind 就像是三位各有所长的魔法师,他们都掌握着控制函数执行上下文(this)的魔法,但各有各的施法方式。本文将用生动形象的比喻和通俗易懂的语言,带你彻底理解这三个方法的联系与区别。

一、三位魔法师的共同使命

首先,我们需要明白这三位魔法师的共同目标:改变函数执行时的this指向。在 JavaScript 中,this的指向往往让人困惑,而这三位魔法师就是来解决这个问题的。

const wizard = {name: 'Merlin',castSpell: function() {console.log(`${this.name} casts a spell!`);}
};const muggle = { name: 'Harry' };// 三位魔法师都能让muggle施法
wizard.castSpell.call(muggle);    // Harry casts a spell!
wizard.castSpell.apply(muggle);   // Harry casts a spell!
const boundSpell = wizard.castSpell.bind(muggle);
boundSpell();                     // Harry casts a spell!

二、各显神通的魔法师们

1. call - 即时通讯专家

call就像是即时通讯软件,特点是立即执行,而且参数要一个一个说清楚

function introduce(greeting, punctuation) {console.log(`${greeting}, I'm ${this.name}${punctuation}`);
}const person = { name: 'Alice' };// 用call:立即执行,参数逐个传递
introduce.call(person, 'Hello', '!'); // Hello, I'm Alice!

特点总结:

  • 立即执行函数
  • 参数逐个传递
  • 适合参数数量确定且较少的情况

2. apply - 批量处理高手

applycall很像,但它更擅长处理批量数据,参数是通过数组传递的。

const numbers = [3, 10, 1, 5];// 用apply可以方便地处理数组参数
Math.max.apply(null, numbers); // 10// 等同于
Math.max(3, 10, 1, 5); // 10

特点总结:

  • 立即执行函数
  • 参数通过数组传递
  • 适合参数数量不确定或较多的情况

3. bind - 预约服务大师

bind与前两位不同,它不立即执行函数,而是返回一个新的函数,你可以稍后调用它。

const flight = {airline: 'Air JS',book: function(flightNum, passenger) {console.log(`${passenger} booked ${this.airline} flight ${flightNum}`);}
};const bookFlight = flight.book.bind(flight, 'JS101');
bookFlight('John'); // John booked Air JS flight JS101
bookFlight('Mary'); // Mary booked Air JS flight JS101

特点总结:

  • 不立即执行,返回新函数
  • 可以预先绑定部分参数
  • 适合需要多次调用的场景

三、魔法师们的对比表格

魔法师执行时机参数传递返回值典型应用场景
call立即执行逐个传递函数返回值明确知道参数个数时
apply立即执行数组传递函数返回值参数个数不确定时
bind延迟执行可部分绑定新函数需要多次调用相同this环境

四、魔法师们的实际应用

1. 借用方法

// 类数组对象借用数组方法
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
Array.prototype.push.call(arrayLike, 'c');
console.log(arrayLike); // {0: 'a', 1: 'b', 2: 'c', length: 3}

2. 函数柯里化

// 使用bind实现函数柯里化
function multiply(a, b) {return a * b;
}const double = multiply.bind(null, 2);
console.log(double(5)); // 10

3. 事件处理

// 在事件处理中保持this指向
const button = document.querySelector('button');
const handler = {message: 'Button clicked!',handleClick: function() {console.log(this.message);}
};// 使用bind确保this正确指向handler
button.addEventListener('click', handler.handleClick.bind(handler));

五、注意事项

  1. 严格模式的影响

    'use strict';
    function fn() { console.log(this); }
    fn.call(null); // null (非严格模式下是window)
    
  2. 箭头函数的特殊性

    const fn = () => console.log(this);
    fn.call({name: 'obj'}); // 仍然指向定义时的this
    
  3. 性能考虑

    • bind会创建新函数,有一定内存开销
    • 在性能敏感的场景,可以考虑用callapply替代

六、现代JavaScript的替代方案

随着ES6的普及,有些场景可以用新特性替代:

// 用扩展运算符替代apply
const nums = [1, 2, 3];
Math.max(...nums); // 替代 Math.max.apply(null, nums)// 用箭头函数替代bind
const obj = {name: 'obj',fn: function() {setTimeout(() => {console.log(this.name); // 箭头函数自动绑定this}, 100);}
};

结语

callapplybind是JavaScript中控制this指向的三大神器。虽然现代JavaScript提供了箭头函数等新特性,但理解这三个方法仍然是掌握JavaScript核心概念的关键。记住:

  • call - “立即执行,参数一个一个说”
  • apply - “立即执行,参数打包成数组”
  • bind - “先预约,稍后执行”

掌握了这三位魔法师的技巧,你就能在JavaScript的世界里更加游刃有余地控制函数的执行上下文了!

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

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

相关文章

【PHP】接入百度AI开放平台人脸识别API,实现人脸对比

目录 一、需求 二、准备工作 1、申请服务 2、创建应用,获取开发密钥 3、官方开发文档 4、测试人像图片 三、PHP接入 1、鉴权,获取access_token 2、人脸对比 四、完整代码 一、需求 现在人脸识别、人脸对比技术越来越成熟,使用越来越…

【东枫科技】DreamHAT+

DreamHAT 是一款顶部附加硬件 (HAT) 套件,可为 Raspberry Pi 提供 60GHz 毫米波雷达供您使用。 全尺寸 HAT 包含一个英飞凌 BGT60TR13C 芯片,具有单个发射天线和三个接收器(TX/RX),通过 GPIO 引脚和 SPI 连接到 Raspbe…

Spring Boot + MongoDB:从零开始手动配置 MongoConfig 实战

前言 你以为只要写上 spring.data.mongodb.*,就能一劳永逸,MongoDB 立马听话?别天真,这只是入门级操作,像是拿个自动挡钥匙,开个小车溜达溜达,远远算不上高手操作。当项目需求变得复杂,连接字符串需要灵活配置,或者多数据源并行作战时,自动配置的魔法显得捉襟见肘。…

建筑节能目标下,楼宇自控系统以高效运行助力节能减碳

随着全球气候变化问题日益严峻,节能减排已成为各国政府和企业的重要任务。在建筑领域,楼宇自控系统(Building Automation System, BAS)作为实现建筑节能目标的关键技术,正发挥着越来越重要的作用。根据中国政府发布的《…

LOVON——面向足式Open-Vocabulary的VLN导航:LLM做任务分解、YOLO11做目标检测,最后L2MM将指令和视觉映射为动作,且解决动态模糊

前言 因为项目需要(比如我们在做的两个展厅讲解订单),近期我一直在研究VLN相关,有些工作哪怕暂时还没开源(将来可能会开源),但也依然会解读,比如好处之一是构建完整的VLN知识体系,本文便是其中一例 我在解读过程中&am…

在线免费的AI文本转语音工具TTSMaker介绍

TTSMaker是一个在线的文本转语音工具, 支持多语言和中文方言,不同的语言和方言单次转换的字符上限从200-10000 不同,转换的效果还不错,听不出明显的AI痕迹。 工具的网址是:https://ttsmaker.cn/。 工具的界面如上&…

【AI问答】PromQL中interval和rate_interval的区别以及Grafana面板的配置建议

问题1:interval和rate_interval的区别 在PromQL中确实有 $__rate_interval 这个特殊的变量,它与 $__interval 有不同的用途和计算方式。 $__interval vs $__rate_interval 1. $__interval 含义:Grafana计算出的基本时间间隔计算方式&#xff…

STM32学习记录--Day5

今天了解了:中断中断有多个类别包括:USART中断,I2C中断等;并通过NVIC来分配中断的优先级EXTIEXTI的内部结构:EXTI线🔧 ​​一、EXTI系统核心架构​​1. ​​中断源输入(左上区域)​​…

CentOS7下同步时间的几种方式(NTP 、Chrony和systemd-timesyncd)

文章目录前言一、NTP (Network Time Protocol) & ntpd1.原理2. 安装与配置(ntp 包)3.NTPd 优缺点对比二、Chrony1.原理2.安装与配置 (chrony 包)3. 优点4. 缺点三、systemd-timesyncd1.原理2.安装与配置 (systemd 自带)3. 优点4. 缺点四、手动同步工具1.ntpdate(已废弃&…

Web3:在 VSCode 中基于 Foundry 快速构建 Solidity 智能合约本地开发环境

相关文章推荐链接Web3专栏https://blog.csdn.net/qq_42392981/category_13016259.html在 VSCode 中基于 Foundry 快速构建 Solidity 智能合约本地开发环境引言1. 开发环境准备(Windows)1.1 安装 VSCode1.2 安装推荐插件1.3 安装 Foundry1.4 验证 Forge 和…

Implement recovery based on PITR using dump file and binlog

模拟生产场景中需要基于某个事务点的恢复,使用存量备份与存量binlog 生成测试数据 (rootlocalhost) [(none)]> create database NanJing; Query OK, 1 row affected (0.01 sec) (rootlocalhost) [test]> use NanJing; Database changed (rootlocalhost) [NanJ…

HTML-取消div,a等标签点击效果

一、背景当标签被设置onclick事件之后,在有些手机浏览器中,点击这些标签,会有点击变色效果。想要取消点击变色效果。通过为div和标签元素添加-webkit-tap-highlight-color样式属性,可以有效地解决这一问题二、解决方案已a标签示例…

VR 三维重建:开启沉浸式体验新时代

在科技飞速发展的今天,VR(虚拟现实)技术已经逐渐渗透到我们生活的各个领域,为我们带来了前所未有的沉浸式体验。而 VR 三维重建作为 VR 技术的重要应用之一,更是让人们能够身临其境地感受各种场景,无论是旅…

iTwinjs 几何 - Curve

CurvePrimitive 常用的见下 LineSegment3d直线段两点直线边、杆件、骨架LineString3d折线多点连续直线轮廓线、路径Arc3d圆弧 / 椭圆弧圆心 半径 起止角圆孔、圆角、弧段BezierCurve3d贝塞尔曲线端点 控制点平滑过渡、动画轨迹BSplineCurve3dB 样条 / NURBS控制点 节点矢…

iPhone 恢复出厂设置是否会删除所有内容?

当你的 iPhone 经常崩溃、出现黑屏死机、卡在加载屏幕上等问题时,你可能会考虑进行恢复出厂设置来修复它。或者在其他情况下,如果你要将使用多年的设备交给新主人,出于安全考虑,也需要进行恢复出厂设置。那么,恢复出厂…

机器学习②【字典特征提取、文本特征处理(TF-IDF)、数据标准化与归一化、特征降维】

文章目录先言一、特征工程概述二、特征提取1.字典特征提取(特征离散化)2.文本特征提取2.1英文文本提取2.2中文文本提取(jieba分词器)3.TfidfVectorizer TF-IDF文本特征词的重要程度特征提取三、数据归一化与标准化1.MinMaxScaler …

3、CC3200串口DMA

先说下CC3200存在2个16*8的fifos, 分别用于发送和接收 当fifos被disable时,将会作为一个1字节深度的保持寄存器, 所以无论fifos是开是关,发送和接收都绕不开fifos DMA 由于发送和接收都绕不过fifos,所以DMA也绕不开FIFOS. MAP_UARTFIFOLevelS…

从游戏NPC到手术助手:Agent AI重构多模态交互,具身智能打开AGI新大门

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《GPT多模态大模型与AI Agent智能体》(跟我一起学人工智能)【陈敬雷编著】【清华大学出版社】 清华《GPT多模态大模型与AI Agent智能体》书籍配套视频课程【陈敬雷…

Lesson 29 Taxi!

Lesson 29 Taxi! taxi n.出租车 同义词:cab n.出租车 相关:taxi meter计价器 taxi stand taxi rank 出租车站 call ataxi 叫车,打车 例句:对不起,请问出租车站在哪里? Excuse me, do you know where the taxi rank is please? land v.着陆,登陆n.陆地…

怎样将allegro的brd文件转化为AD的PCB文件

由于工作需要将allegro的PCB转成ad给同事,在使用AD软件导入Allegro的brd格式文件时出现各种的异常报错弹窗问题,现分享两种将Allegro PCB文件导入到AD中的方法。一、第1种方法使用高版本的AD软件(AD22,同时操作电脑需安装了Allegr…