JavaScript中的call、apply、bind:用法、实现与区别详解(面试常见)

# JavaScript中的call、apply、bind:用法、实现与区别详解## 核心概念
这三个方法都用于改变函数执行时的`this`指向,是JavaScript中函数上下文操作的核心API。## 1. 基本用法对比### call方法
```javascript
function.call(thisArg, arg1, arg2, ...)

特点:

  • 立即执行函数
  • 参数逐个传递
  • 典型应用:类数组转数组
// 将arguments转为真实数组
function example() {const args = Array.prototype.slice.call(arguments);
}

apply方法

function.apply(thisArg, [argsArray])

特点:

  • 立即执行函数
  • 参数以数组形式传递
  • 典型应用:数学计算
// 求数组最大值
const numbers = [5, 6, 2, 3, 7];
const max = Math.max.apply(null, numbers);

bind方法

function.bind(thisArg[, arg1[, arg2[, ...]]])

特点:

  • 返回新函数不立即执行
  • 可预设参数(柯里化)
  • 典型应用:事件回调
// React类组件中绑定this
class Button extends React.Component {constructor() {this.handleClick = this.handleClick.bind(this);}
}

2. 手写实现原理

实现call

Function.prototype.myCall = function(context = window, ...args) {const fnKey = Symbol('fn');context[fnKey] = this;const result = context[fnKey](...args);delete context[fnKey];return result;
};

实现apply

Function.prototype.myApply = function(context = window, args = []) {const fnKey = Symbol('fn');context[fnKey] = this;const result = context[fnKey](...args);delete context[fnKey];return result;
};

实现bind(完整版)

Function.prototype.myBind = function(context, ...bindArgs) {const self = this;const boundFunction = function(...callArgs) {// 判断是否作为构造函数调用const isNew = this instanceof boundFunction;return self.apply(isNew ? this : context,bindArgs.concat(callArgs)};// 保持原型链boundFunction.prototype = Object.create(self.prototype);return boundFunction;
};

3. 三者的核心区别

特性callapplybind
执行时机立即执行立即执行返回绑定函数
参数形式参数列表参数数组参数列表
使用场景明确参数个数时参数数量不定时需要延迟执行时
性能最快次之最慢(需创建新函数)
构造函数可作构造函数可作构造函数可作构造函数

4. 高级应用场景

组合继承(call + prototype)

function Parent(name) {this.name = name;
}function Child(name, age) {Parent.call(this, name);  // 继承属性this.age = age;
}Child.prototype = Object.create(Parent.prototype);

参数柯里化(bind)

function add(a, b, c) {return a + b + c;
}const add5 = add.bind(null, 2, 3);
console.log(add5(5)); // 10 (2+3+5)

替代箭头函数(bind)

// 在需要动态this又需要prototype时
function Logger() {this.log = function() {setTimeout(function() {console.log(this); // 默认window}.bind(this), 1000);};
}

5. 面试常见问题

Q1:这三个方法改变this指向的原理是什么?

本质是通过将函数临时挂载到目标对象上调用,利用隐式绑定规则实现this指向改变

Q2:bind后的函数还能改变this吗?

不能,bind是硬绑定,但可通过new运算符覆盖

Q3:如何实现bind的new操作兼容?

在手写实现中通过this instanceof boundFunction判断

Q4:这三个方法在严格模式下的表现?

当thisArg为null/undefined时:

  • 非严格模式:替换为全局对象
  • 严格模式:保持为null/undefined

掌握这三个方法不仅能应对面试,更能写出更灵活的JavaScript代码。建议通过实际项目练习加深理解!

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

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

相关文章

使用vue开发浏览器chrome插件教程,及之间的消息通信

基本介绍 开发浏览器插件,首先需要先了解他的结构,浏览器扩展通常包括以下几个部分 ├── manifest.json ├── package.json ├── vite.config.js ├── src ├── background │ └── index.js ├── content │ └── content.js ├── …

论文笔记(八十八)MLCVNet: Multi-Level Context VoteNet for 3D Object Detection

MLCVNet: Multi-Level Context VoteNet for 3D Object Detection 文章概括摘要I. 引言2. 相关工作2.1. 基于点云的 3D 目标检测2.2. 上下文信息 3. 方法3.1. VoteNet3.2. PPC 模块3.3. OOC 模块3.4. GSC 模块 4. 结果与讨论4.1. 数据集4.2. 训练细节4.3. 与最先进方法的比较4.4…

Redis初识第四期----Hash的命令和应用场景

首先为了区分Redis的键值对存储的key-value,Hash中的键值对称为field-value。 命令 1.Hset Hset key field value [field value] 返回值为设置成功的field-value的个数。 2.Hget Hget key field 返回为value 3.Hexists Hexists key field 判断是否存在&a…

【大数据技术栈】数据管理范畴常用大数据技术栈

一、技术栈分层架构 大数据技术栈通常分为四个核心层级: 数据采集层 负责多源异构数据的实时/批量采集 日志采集: F l u m e Flume Flume、 L o g s t a s h Logstash Logstash消息队列: K a f k a Kafka Kafka、 R a b b i t M Q RabbitMQ …

安全左移(Shift Left Security):软件安全的演进之路

文章目录 一、背景:传统安全的尴尬处境二、安全左移:让安全成为开发的“第一等公民”三、安全左移的关键实施阶段1. 需求阶段:嵌入安全需求建模2. 设计阶段:威胁建模与架构审计3. 编码阶段:安全编码规范与静态分析4. 构…

固定债可以卖call吗

我们都知道如果持有tlt,可以卖call来赚取时间价值,如果我买固定到期的美债而不是etf,有类似的操作吗,我可以卖call吗 以下是关于直接持有固定到期美债并尝试卖出看涨期权的详细分析: 一、直接持有美债与ETF&#xff08…

fish安装node.js环境

为什么强调fish shell,因为fish shell的缘故,不能直接执行node.js官网的命令 好的,您遇到了一个非常典型且重要的问题。请仔细阅读我的分析,这能帮您彻底解决问题。 问题诊断 您看到的所有错误,归根结底有两个核心原…

记一次Ubuntu22安装MongoDB8并同步本地数据过程

1. 效果展示 2. 安装MongoDB 8 根据官方文档https://www.mongodb.com/zh-cn/docs/manual/tutorial/install-mongodb-on-ubuntu/一顿操作即可 2.1 配置微调支持远程访问 修改配置文件,默认/etc/mongod.conf # network interfaces net:port: 27017bindIp: 0.0.0.02.2 新增adm…

HarmonyOS应用开发高级认证知识点梳理 (三)状态管理V2装饰器核心规则

以下是针对HarmonyOS应用开发高级认证备考的‌状态管理V2装饰器核心规则‌知识点系统梳理: 一、核心装饰器分类与功能 1. ‌组件声明装饰器‌ ComponentV2‌ (1)基础定义与限制 功能定位‌ 用于装饰自定义组件,启用V2状态管理能力,需配…

SAP资产记账相关业务成本中心为空的问题

用户在资产记账时,发现字段“成本中心”是空且为灰色的,并没有显示资产对应的成本中心,如下图所示: 首先,关于资产购置记账的相关业务,成本中心要不要显示?其实是可以不显示的,它是来…

智源大会AI安全论坛:深挖风险红线,探讨应对措施

6月7日,在与安远AI联合主办的智源大会“AI安全论坛”上,来自MIT、清华、复旦、人大、智源、多伦多大学、新加坡管理大学、Redwood Research、瑞莱智慧和安远AI 的学者与技术专家同台,以“AI安全”为核心议题,从主旨报告&#xff0…

电机控制的一些笔记

1. 电角度和机械角度 电角度 机械角度 * 磁极对数 机械角度就是实际的空间几何角度,范围是0-360 https://blog.csdn.net/leekay123/article/details/108655482 https://www.bilibili.com/video/BV11Q4y1Y7kR/?spm_id_from333.788.recommend_more_video.1&vd…

c#手动编译

一、配置环境变量 点击环境变量,在用户变量的path进行新建,点击编辑 点击新建 点击新建 添加文件目录 这是我的可能不一样,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 输入 点击确定,就可以了 二、建立cs文件 代码实例…

pcap流量包分析工具设计

在复杂的网络世界中,数据包是信息的载体,但也可能成为风险的源头。无论是开发者调试接口,还是安全人员排查异常,都需要一个能够看透数据本质的“眼睛”。然而,专业的网络分析工具往往过于复杂,不适合快速定…

Qt 安装与项目创建

一、Qt 介绍 1. Qt是什么? Qt是一个跨平台的 C 开发库,主要用来开发图形用户界面(Graphical User Interface,GUI)程序,当然也可以开发不带界面的命令行(Command User Interface,CU…

基于注意力机制的方法预测的体重

我们有一些已知的身高(作为键 K K K)和对应的体重(作为值 V V V)。现在,我们想使用一种基于注意力机制的方法来“查询”一个特定身高(比如 170cm)对应的体重。虽然这通常不是注意力机制的典型…

Modbus TCP 进阶:基于以太网的远程设备控制(一)

Modbus TCP 基础回顾 ** 在工业自动化领域,Modbus TCP 是一种广泛应用的通信协议,它基于以太网,为设备之间的通信搭建了桥梁,实现了远程设备的高效控制。Modbus TCP 是 Modbus 协议家族中的一员,它在传统 Modbus 协议…

linux魔术字定位踩内存总结

0,数据被改写时我们需要怎么定位,我们首先需要确认数据是逻辑上被改写还是踩内存被改写的。 1,当数据被踩时,也就是出现数据异常时,并且可以稳定复现时,我们确认时踩固定内存时,我们可以使用魔术字定位问题。 代码举例查看确认。 #include <stdio.h> #include…

浅谈Docker Kicks in的应用

正因为传统部署的麻烦&#xff0c;我们希望减少整个安装过程&#xff0c;将其简单化&#xff0c;以下介绍两个思路&#xff1a; 思路一&#xff1a;安装 Docker 后安装 Ghost&#xff0c;并且直接暴露 80 端口&#xff0c;此时所有请求由 Docker 内的 Express 服务器处理&…

【Rust + Actix Web】现代后端开发:从零构建高并发 Web 应用

目录 项目概述环境准备项目创建与依赖配置系统架构设计核心代码实现1. 数据库模型 (src/models.rs)2. 应用状态管理 (src/state.rs)3. 核心业务逻辑 (src/handlers.rs)4. 主应用入口 (src/main.rs) 高并发优化策略1. 异步处理模型2. 连接池配置优化3. 缓存策略设计 性能测试结果…