JS 中bind、call、apply的区别以及手写bind

1.作用

call、apply、bind作用是改变函数执行的上下文,简而言之就是改变函数运行时的this指向

那么什么情况下需要改变this的指向呢?下面举个例子

var name = "lucy";
var obj = {name: "martin",say: function () {console.log(this.name);},
};
obj.say(); //martin,this指向obj
setTimeout(obj.say, 0); //lucy,this指向window

从上面可以看到,正常情况下say方法输出martin

但是我们把say放在setTimeout方法中,在定时器中是作为回调函数来执行的,因此回到主栈执行时是在全局执行上下文的环境中执行的,这时候this指向window,所以输出lucy

我们实际需要的是this指向obj对象,这时候就需要改变this指向了

setTimeout(obj.say.bind(obj),0)

2.区别

下面再来看看apply、call、bind的使用

2.1.apply

apply接收1两个参数,第一个参数是this指向,第二个参数是函数接收的参数,以数组的形式传入

改变this指向后原函数会立即执行,且此方法只是临时改变this指向一次

function fn(...args) {console.log(this, args);
}
let obj = {myname: "张三",
};
fn.apply(obj, [1, 2]); //this会变成传入的obj,传入的参数必须是一个数组
fn(1, 2); //this会变成window,传入的参数必须是一个数组

当第一个参数为null、undefined的时候,默认指向window(在浏览器中)

fn.apply(null, [1, 2]); //this会变成window,传入的参数必须是一个数组
fn.apply(undefined, [1, 2]); //this会变成window,传入的参数必须是一个数组

2.2.call

call方法的第一个参数也是this指向,后面传入的是一个参数列表

跟apply一样,改变this指向后原函数会立即执行,且此方法只是临时改变this指向一次

function fn(...args) {console.log(this, args);
}
let obj = {myname: "张三",
};
fn.call(obj, 1, 2); //this会变成传入的obj,传入的参数必须是一个一个的
fn(1, 2); //this会变成window

同样的,当第一个参数为null、undefined的时候,默认指向window(在浏览器中)

fn.call(null, 1, 2); //this会变成window,传入的参数必须是一个一个的
fn.call(undefined, 1, 2); //this会变成window,传入的参数必须是一个一个的

2.3.bind

bind方法和call很相似,第一个参数也是this的指向,后面传入的也是一个参数列表(但是这个参数列表可以分多次传入)

改变this指向后不会立即执行,而是返回一个永久改变this指向的函数

function fn(...args) {console.log(this, args);
}
let obj = {myname: "张三",
};
const bindFn = fn.bind(obj); //this指向会变成传入的obj,bind不是立即执行需要执行一次
bindFn(1, 2); //this指向obj,传入的参数必须是一个一个的
fn(1, 2); //this指向window

2.4.小结

从上面可以看到,apply、call。、biond三者的区别在于:

  • 三者都可以改变函数的this对象指向
  • 三者第一个参数都是this要指向的对象,如果没有这个参数或参数为undefined或null,则默认指向全局window
  • 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入
  • bind是返回绑定this之后的参数,apply、call则是立即执行

3.实现

实现bind的步骤,我们可以分解成三部分:

  • 修改this指向
  • 动态传递参数1 // ⽅式⼀: 只在bind中传递函数参数
    2 fn.bind(obj,1,2)()
    3 // ⽅式⼆: 在bind中传递函数参数,也在返回函数中传递参数
    4 fn.bind(obj,1)(2)
  • 兼容new关键字

整体实现代码如下:

Function.prototype.myBind = function (context) {// 判断调用对象是否为函数if (typeof this !== "function") {throw new TypeError("Error"); //判断调用对象是否为函数}// 获取参数const args = [...arguments].slice(1),fn = this;return function Fn() {// 根据调用方式,传入不同绑定值return fn.apply(this instanceof Fn ? new fn(...arguments) : context,args.concat(...arguments));};
};

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

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

相关文章

vue2(7)-单页应用程序路由

1.单页应用程序如 单页:网易云,多页:京东单页应用程序,之所以开发效率高,性能高,用户体验好最大的原因是:页面按需更新 要按需更新,就要明确访问路径和组件的关系这时候就要用…

vue中通过heatmap.js实现热力图(多个热力点)热区展示(带鼠标移入弹窗)

直接上完整代码&#xff01;记录实现方式 注意heatmap.min.js需要通过heatmap.js提供的下载地址进行下载&#xff0c;地址放在下边 url&#xff1a;heatmap GIT地址 <template><div class"heatmap-view" ref"heatmapContainer"></div&g…

配置Kronos:k线金融大模型

github地址 网页btc预测demo使用的Kronos-mini模型 huggingface的仓库 文章目录配置环境安装python环境获取市场数据的库通过webui使用example中的例子prediction_example.py补充说明根据原例优化的代码CryptoDataFetcher单币对多周期预测配置环境 使用conda的环境. 首先进行换…

【Deep Learning】Ubuntu配置深度学习环境

【start: 250715】 文章目录ubuntu与深度学习安装cuda查看显卡信息&#xff08;nvidia-smi&#xff09;升级驱动下载cuda安装conda安装anaconda默认指向自己的conda初始化conda确认 conda.sh 被加载安装cuda-toolkit直接安装cuda-toolkit&#xff08;高级的&#xff09;安装高于…

车载数据采集(DAQ)解析

<摘要> 车载数据采集&#xff08;DAQ&#xff09;软件模块是现代汽车电子系统的核心组件&#xff0c;负责实时采集、处理、记录和传输车辆运行数据。本文系统解析了DAQ模块的开发&#xff0c;涵盖其随着汽车智能化演进的历史背景&#xff0c;深入阐释了信号、协议、缓存等…

强化学习框架Verl运行在单块Tesla P40 GPU配置策略及避坑指南

1.前言 由于比较穷,身边只有1块10年前的Tesla P40 GPU卡(2016年9月发布),想利用起来学习强化学习框架Verl。程序员学习开源代码,大部分人的第一直觉不是分析模块组成,而是跑起来试试,然后去debug一下后面的运行逻辑。 由于在官方部署指导文档中并未指明跑通Verl的最低…

leetcode169.多数元素

题目描述给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。题目解法博耶-摩尔多数投票算法&#xff08;英语&#xff1a;Boyer–Moore…

基于机器学习的P2P网贷平台信用违约预测模型

使用平台提供的借款人信息&#xff08;年龄、收入、历史信用等&#xff09;和借款信息&#xff0c;构建一个二分类模型来预测借款人是否会违约。重点解决类别不平衡问题和模型可解释性。逻辑回归、随机森林、XGBoost、SMOTE过采样、模型评估&#xff08;AUC, KS, F1-Score&…

豆瓣网影视数据分析与应用

源码链接&#xff1a;点击下载源码 相关文档&#xff1a;点击下载相关文档 摘 要 随着互联网的快速发展&#xff0c;豆瓣网作为一个综合性的影视评分和评论平台&#xff0c;积累了大量的用户数据&#xff0c;这些数据为影视分析提供了丰富的素材。借助Hadoop这一大数据处理框…

四、计算机网络与分布式系统(中)

一、局域网与广域网1、局域网&#xff08;1&#xff09;定义将有限地理范围内的多台计算机通过传输媒体连接&#xff0c;借助网络软件实现设备间通信与资源共享的通信网络&#xff08;2&#xff09;特点1.地理范围小&#xff1a;通常为数百米至数公里内。2.传输速率高&#xff…

Python 面向对象实战:私有属性与公有属性的最佳实践——用线段类举例

描述 在绘图软件、GIS、CAD 或简单的图形编辑器中&#xff0c;线段&#xff08;Segment&#xff09;是非常基础的对象。每个线段有两个端点&#xff08;x1,y1&#xff09;和&#xff08;x2,y2&#xff09;。在实现时我们通常希望&#xff1a; 封装端点数据&#xff08;防止外部…

流式细胞术样本处理全攻略(一):组织、血液、体液制备方法详解

摘要 流式细胞术作为多参数、高通量的细胞分析技术,在细胞表型鉴定、免疫反应研究、疾病机制探索及药物效果评估中发挥关键作用。而样本制备是流式实验成功的核心前提,需将不同来源样本处理为单颗粒悬液,并最大程度减少细胞死亡与碎片干扰。本文针对组织、外周血 / 骨髓、体…

【C#】理解.NET内存机制:堆、栈与装箱拆箱的底层逻辑及优化技巧

文章目录前言一、栈与堆1.1 栈&#xff08;Stack&#xff09;1.1.1 基本信息1.1.2 特点1.2 堆&#xff08;Heap&#xff09;1.2.1 基本信息1.2.2 特点1.3 从代码中窥见堆栈二、装箱与拆箱2.1 装箱2.2 拆箱2.3 如何避免不必要的装箱与拆箱2.3.1 泛型集合2.3.2 泛型参数总结前言 …

人工智能学习:Transformer结构中的子层连接(Sublayer Connection)

Transformer结构中的子层连接(Sublayer Connection) 一、子层连接介绍 概念 子层连接(Sublayer Connection),也称为残差连接(Residual Connection),是Transformer模型中的一个关键设计,用于将多个子层(如自注意力层和前馈全连接层)组合在一起。它通过残差连…

解锁Roo Code的强大功能:深入理解上下文提及(Context Mentions)

在AI使用中&#xff0c;我们经常需要AI或AI工具描述代码中的某个具体部分。但如果工具能直接“看到”所指的代码、错误信息甚至终端输出&#xff0c;协作效率会不会大幅提升&#xff1f;这正是 Roo Code 的“上下文提及&#xff08;Context Mentions&#xff09;”功能所要实现…

第5篇、 Kafka 数据可靠性与容错机制

在分布式消息队列系统中&#xff0c;数据可靠性 与 容错能力 是核心指标。Kafka 作为高吞吐、可扩展的流式处理平台&#xff0c;依靠副本复制、Leader 选举和 ISR 机制&#xff0c;保证了在节点故障时消息依然能够可靠传输与消费。 &#x1f4da; 目录 理论基础 一、数据复制…

Excel表格如何制作?【图文详解】表格Excel制作教程?电脑Excel表格制作?

一、问题背景 在日常办公中&#xff0c;无论是统计数据、整理报表&#xff0c;还是记录信息&#xff0c;Excel表格都是必不可少的工具。 但对新手来说&#xff0c;打开Excel后面对空白的单元格&#xff0c;常常不知道从何下手——不知道怎么选表格范围、怎么加边框让表格显形、…

阿里兵临城下,美团迎来至暗时刻?

9月10日&#xff0c;赶在阿里巴巴成立26周年之际&#xff0c;高德地图推出了首个基于用户行为产生的榜单“高德扫街榜”&#xff0c;被定义为“阿里生活服务超级新入口”&#xff0c;试图重新构建一套线下服务的信用体系。 上线第二天&#xff0c;就有媒体报道称“使用高德扫街…

Android逆向学习(十一) IDA动态调试Android so文件

Android逆向学习&#xff08;十一&#xff09; IDA动态调试Android so文件 一、 写在前面 这是吾爱破解论坛正己大大的第12个教程&#xff0c;并且发现一个神奇的事情&#xff0c;正己大大的教程竟然没有第11个&#xff0c;感觉很奇怪 写这个博客的主要原因是希望提供一种新的解…

Django全栈班v1.03 Linux常用命令 20250911 下午

课程定位 命令行 ! 黑客专属。 这套视频带你从Linux小白到命令行大师&#xff0c;涵盖文件管理文本处理系统监控网络操作。 零基础也能30分钟掌握程序员必备的技能。 课程亮点 1、零基础友好&#xff1a;从最基础的ls&#xff0c;cd命令开始&#xff0c;循序渐进 2、实战导向&a…