【bind()函数】JavaScript手写bind()及详解-超详细~~~

article/2025/10/19 4:19:15

这两天学习了手写call、apply、bind,手写bind思考了很久才实现了MDN的示例的结果,所以记录下来~

因为是第一篇文章,所以可能存在一些错误,希望各位大佬批评指正,不吝赐教。

也欢迎不懂的同学留言评论一起交流~~~

----------------------------------------------------------------------------

目录

解析①:普通函数的调用 + 柯里化的实现

解析②: 通过new操作符调用 + 柯里化的实现

示例①:普通函数的调用 + 柯里化的实现

示例②:通过new操作符调用 + 柯里化的实现


bind与call和apply方法不同,bind返回的是创建的新函数,而不是像call、apply那样立即执行调用它的函数。

基于对bind返回的新函数不同的使用方法,我们在手写bind的时候从实现以下两个方面来入手:

① 普通函数的调用 + 柯里化的实现

② 通过new操作符调用 + 柯里化的实现

对这两个使用方法不熟悉的同学可以先看下后面的示例。

bind的实现会用到call/apply的方法,如果对这两个函数的原理不太懂的同学可以先看一下手写call和apply~【手写call和apply】详解手写call和apply函数JavaScript_Jennifer0204的博客-CSDN博客

Function.prototype.bind2 = function(asThis,...args) {//这里的this就是调用bind2的函数(普通函数this指向调用者)if (typeof this !== "function") {throw new TypeError("Not a Function");}//  这里保存调用bind的函数以及传给bind后面的参数。var origin = this;let  args0 = args;function bound(...args) {if(this instanceof bound) //如果是new的形式来使用绑定函数的return new origin( ...args0,...args)else //如果是普通函数的形式来使用绑定函数的(基本上与call、apply无区别,实现柯里化即可)return origin.call(asThis, ...args0,...args);}bound.prototype = origin.prototype;return bound;}

解析①:普通函数的调用 + 柯里化的实现

如果是正常的普通函数的调用方法来调用bind返回的函数,那么直接返回像调用call函数那样返回,第一个参数值就是传入bind的asThis值。注意要将前后传入的参数(两次...arg收集到的)同时收集到call函数的参数中,从而实现柯里化。

解析②: 通过new操作符调用 + 柯里化的实现

如果通过new来调用bind生成的函数(绑定函数)情况又有所不同了

 如何判断时通过new来调用的呢?我们知道,通过new 某个构造函数时,构造函数里的this会指向一个新创建的对象,然后执行构造函数中的代码,这个对象的[[prototype]]会指向构造函数的prototype属性,那么此时只需要在绑定函数(bind的返回函数——bound,此时也是作为一个构造函数来使用的)内部判断this是否指向bound的原型即可。

if(this instanceof bound) return new origin( ...args0,...args)
//判断条件也可写bound.prototype.isPrototypeOf(this) 

所以在通过new调用绑定函数时, 则应忽略asThis值,相当于直接new一个Origin的实例对象即可,当然参数也应实现柯里化。

还有一点需要注意的是,new调用绑定函数时,绑定函数的prototype属性存在与返回的实例对象的原型链上,将bound的prototype指向origin的prototype属性即可。

 bound.prototype = origin.prototype;

以下是代码测试,部分参考了MDN的示例。Function.prototype.bind() - JavaScript | MDN

示例①:普通函数的调用 + 柯里化的实现

//代码测试
//----------普通函数的调用
let classRoom107 = {desk:100,chair:97
}function course(teacherName,studentNumber) {console.log(`This course is taught by ${teacherName},today there are ${studentNumber} students in this class.`);
}//教室和老师的名字都固定了,只是每天上课的人数不同。
//这里'预设的初始参数' 就是'pink'
let course_css = course.bind2(classRoom107,'pink');
let Monday = course_css(9999);
// This course is taught by pink,today there are 9999 students in this class.//只固定了教室,老师的名字和上课的人数不同。
let course_happy = course.bind2(classRoom107);
let Wed = course_happy('马冬梅',9);
// This course is taught by 马冬梅,today there are 9 students in this class.

可以通过这个示例理解一下bind的含义,传入bind一个或多个参数时,绑定函数相当于有了固定的一个或多个参数,比方说course_css就是固定了classRoom和老师,只能指定每天上课的人数。course_happy只指定了上课教室,而上课老师和上课人数都是待定的。

示例②:通过new操作符调用 + 柯里化的实现

function Positon(x,y){this.x = x;this.y = y;
}
Positon.prototype.toAxis = function() {return  `(${this.x},${this.y})`;
}let a1 = new Positon(1,3);
console.log(a1.toAxis());//(1,3)let emptyObj = {};
let X_5_Line =  Positon.bind2(emptyObj,5);
let a2 = new X_5_Line(8);
console.log(X_5_Line instanceof Positon);//false
console.log(X_5_Line.constructor.name);//"Function"
console.log(a2 instanceof Positon);//true
console.log(a2 instanceof X_5_Line);//true
console.log(a2.constructor.name);//Positon
console.log(a2.toAxis());//(5,8)//也可以作为普通函数调用,但是最好不要这样做。
X_5_Line(8);
console.log(emptyObj);//{ x: 5, y: 8 }

实例②可以参考下面这张图来看,我认为需要关注的几点:

1. 表面上看a2是X_5_Line new出来的,但实际上这个bound构造函数自己返回了非空对象,所以a2的constructor不是X_5_Line而是Position;

2. 不用new操作符调用X_5_Line时,相当于调用origin.call(asThis, ...args0,...args),也就是Position.call(emptyObj, 5,8),执行构造函数的代码this.x =  5 , this.y = 8,所以最后empty不为空。

 


http://chatgpt.dhexx.cn/article/jmr0A9JT.shtml

相关文章

2.深入了解bind函数

bind函数 1.查看方法2.详细解说(中文)bind函数: 3.bind文档 1.查看方法 使用指令:man bind 2.详细解说(中文) bind函数: 1.功能: bind函数把一个本地协议地址赋予一个套接字。 对…

C/C++ bind函数应用详解

文章目录 知识前导头文件bind介绍bind函数&#xff1a;bind简述&#xff1a; placeholders 用法探究单个参数多个参数成员函数 知识前导 头文件 #include <functional>bind介绍 bind函数&#xff1a; 使用规则&#xff1a; auto newCallable bind(callable, arg_li…

c++bind函数使用

总述 最近写代码的时候看到代码使用了bind&#xff0c;一个参数绑定的标准库函数。程序是这么写的&#xff0c; speaker_play_routine_ new boost::thread (boost::bind(&Speaker::playRoutine, this)); 这是我们一个语音播放的一行代码。 其中 boost::thread是新建一个线…

c++ bind 函数讲解

1.bind 函数的使用详解 可以将bind函数看作一个通用的函数适配器&#xff0c;它接受一个可调用对象&#xff0c;生成一个新的可调用对象来“适应”原对象的参数列表。 调用bind的一般形式&#xff1a;auto newCallable bind(callable,arg_list); 其中&#xff0c;newCallab…

Bind函数详解

自己开发了一个股票软件&#xff0c;功能很强大&#xff0c;需要的点击下面的链接获取&#xff1a; QStockView股票智能分析报警软件下载链接 - 一字千金 - 博客园 Bind函数详解 目录 1 简介... 1 2 使用实例... 1 2.1 bind函数常规使用... 1 2.2 …

网络编程之bind函数

基本TCP客户端/服务器程序的套接字函数 1、bind函数把一个本地协议地址赋予一个套接字。对于网际协议&#xff0c;协议地址是32位的IPv4地址或是128位的IPv6地址与16位的TCP或UDP端口号的组合。 #include<sys/socket.h> int bind(int sockfd, const struct sockaddr, …

一阶数字低通滤波器设计matlab

一阶数字低通滤波器传递函数为&#xff1a; ωc2πfc ωc​为滤波截止角频率 :截止频率&#xff0c;单位&#xff1a; HZ 对低通滤波器进行离散化 一 后向差分法 变换公式为&#xff1a; s(1−z−1)/Ts​ Ts&#xff1a;采样频率 将变化公式带入传递函数&#xff0c;可得…

一文读懂滤波器的线性相位,全通滤波器,群延迟

一文读懂滤波器的线性相位&#xff0c;全通滤波器&#xff0c;群延迟 1. 延迟2. 全通滤波器3.相位延迟和群延迟4. 实际生活中的例子总结&#xff1a; 数字信号处理最常见的面试题&#xff0c;请简述FIR和IIR的区别。其中的一个区别是FIR可以方便地实现线性相位。那这个线性相位…

一阶RC低通滤波器的数学模型及算法实现

一阶RC低通滤波器的数学模型及算法实现 1. 一阶RC低通滤波器的连续域数学模型1.1 数学模型的推导1.2 频率特性1.3 物理作用 2. 一阶RC低通滤波器的算法推导2.1 离散化2.2 滤波系数 3. 一阶RC低通滤波器的C语言实现4. 缺点及改善方法4.1 缺点4.2 改善方法——动态调整滤波系数4.…

数字 一阶低通滤波器 详细分析

事件的起因是下图1&#xff0c;朋友偶然说到一阶低通滤波器&#xff0c;借此来详细介绍一阶低通滤波器的原理&#xff0c;并附上matlab仿真程序代码。图1中的一阶低通数字滤波器的公式为Eq(1)&#xff1a; y(n) q*x(n) (1-q)*y(n-1) Eq(1) 其中&#xff0c;y(n)表示当前…

【滤波器学习笔记】一阶RC低通滤波

一阶RC低通滤波 从模拟到数字 本文整理自网络、《匠人手记》等书籍文章 模拟电路低通滤波时域、频域软件低通滤波 典型电路 图1 典型RC电路 直流、交流、脉冲信号都可以用它 时域 电容电流&#xff1a; Icdqdtd(C∙Uo)dtCdUodt 基尔霍夫电压定律得&#xff1a; UiRCdUo…

一阶低通数字滤波

一阶低通滤波算法&#xff1a; 3、 一阶低通滤波优缺点 一阶低通滤波数学意义&#xff1a;一阶低通滤波法采用本次采样值与上次滤波输出值进行加权&#xff0c;得到有效滤波值&#xff0c;使得输出对输入有反馈作用。 优缺点&#xff1a;滤波系数越小&#xff0c;滤波结果越平稳…

MATLAB—FIR数字滤波器设计

目录&#xff1a; 1 FIR滤波器的原理2 FIR滤波器的特点2.1 相位特性2.1.1 偶对称2.1.2 奇对称 2.2 幅度特性 3 几种滤波器函数3.1 fir1()3.2 fir2()3.3 kaiserord()3.4 firpm() 4 仿真实例4.1 代码4.2 仿真分析 本文是基于MATLAB的数字滤波器设计&#xff0c;所有数据基于计算机…

窗函数法设计FIR中,如何选择窗函数和阶数N

在用窗函数法设计FIR滤波器时&#xff0c;给出了滤波器要求的具体指标&#xff0c;包括通带频率fp、阻带频率fs、通带波纹Rp和阻带衰减As等&#xff0c;有了这些指标后&#xff0c;是否什么窗函数都可以选择呢&#xff1f;答案是否定的。那么怎么选择窗函数呢&#xff1f;在本小…

一阶RC低通滤波器(二)

这篇文章补充下前面讲的一阶低通滤波器。在母线电压采样或是在电机的三相端电压采样时&#xff0c;往往是先分压&#xff0c;再经过RC低通滤波器。电路图如下&#xff1a; 1&#xff1a;先求输出和输入的关系&#xff08;Uao/Ua&#xff09; 从上式可以看出系统相当于一个典…

二阶有源滤波器设计

1引入 为什么要用有源二阶滤波器&#xff1f; (1)从有源来说 对于无源二阶低通滤波器&#xff1a; 其幅頻方程为&#xff1a; 我们从中可以看出其通带截止频率为 有其品质因子为0.372。 我们根据上图得到二阶无源低通滤波器的品质因子只有0.372&#xff0c;如果希望Q大于0.5…

滤波算法——均值滤波,中值滤波,一阶(αβ)滤波,卡尔曼滤波

滤波算法——均值滤波&#xff0c;中值滤波&#xff0c;一阶(αβ)滤波&#xff0c;卡尔曼滤波 因工作涉及到数据滤波(滤噪)处理&#xff0c;汇总了一些网上简单的滤波算法&#xff0c;方便日后查看。 滤波算法包括&#xff1a;均值滤波&#xff0c;中值滤波&#xff0c;一阶…

一阶滤波器

1. 一阶滤波算法的原理 一阶滤波&#xff0c;又叫一阶惯性滤波&#xff0c;或一阶低通滤波。是使用软件编程实现普通硬件RC低通滤波器的功能。 一阶低通滤波的算法公式为&#xff1a; Y(n)αX(n) (1-α)Y(n-1) 式中&#xff1a;α滤波系数&#xff1b;X(n)本次采样值&…

FIR数字滤波器设计

今天给大侠带来FIR数字滤波器设计&#xff0c;由于篇幅较长&#xff0c;分三篇。今天带来第三篇&#xff0c;FIR数字滤波器设计&#xff0c;包括窗函数法设计FIR滤波器、频率采样法设计FIR滤波器以及基于firls函数和remez函数的最优化方法设计FIR滤波器。话不多说&#xff0c;上…

一阶二阶数字滤波器笔记

数字滤波器 一阶数字滤波器时域分析频域分析数字化代码示例 二阶巴特沃斯低通滤波器S域和Z域的频率关系分析巴特沃斯滤波器举例说明代码示例 声明&#xff1a;感谢知乎大佬的文章&#xff0c;原文链接 数字滤波器实现方法是把滤波器所要完成的运算编成程序并让计算机执行,也就…