JS基础面试题之手写bind

news2025/1/19 3:19:07

JS基础面试题之手写bind

  • 手写bind
    • 返回函数的模拟实现
    • 传参的模拟实现
    • 构造函数效果的模拟实现
    • 构造函数效果的优化实现
    • 最终版

手写bind

bind()方法会创建一个新的函数。当这个函数被调用时,bind()的第一个参数将作为它的运行时的this,之后的一序列参数将会在传递的实参前传入作为它的参数。

由此,我们可以首先得出bind函数的两个特点:

  • 返回一个函数。
  • 可以传入参数。

返回函数的模拟实现

var foo = {
	value:1
};
function bar(){
	console.log(this.value);
}
//返回一个函数
var bindFoo = bar.bind(foo);

bindFoo();//1

关于指定this的指向,我们可以使用call或者apply实现。

//第一版
Function.prototype.bind2 = function (context){
	var self = this;
	//考虑到绑定函数可能是有返回值的,加上return
	return function(){
		return self.apply(context);
	}
}

传参的模拟实现

接下来,关于参数的传递:

var foo = {
	value:1
};
function bar(name,age){
	console.log(this.value);
	console.log(name);
	console.log(age);
}
var bindFoo = bar.bind(foo,'kin');
bindFoo('18');
//1
//kin
//18

当需要传name和age两个参数时,可以在bind的时候,只传一个name,在执行返回的函数的时候,再传另一个参数age。
这里如果不适用rest,使用arguments进行处理:

//第二版
Function.prototype.bind2 = function(context){
	var self = this;
	//获取bind2函数从第二个参数到最后一个参数
	var args = Array.prototype.slice.call(arguments,1);
	return function(){
		//这个时候的arguments是指bind返回的函数传入的参数
		var bindArgs = Array.prototype.slice.call(arguments);
		return self.apply(context,args.concat(bindArgs));
	}
}

构造函数效果的模拟实现

bind还有一个特点,就是

一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的this值被忽略,同时调用时的参数被提供给模拟函数。

也就是说当bind返回的函数作为构造函数的时候,bind指定的this值会失效,但传入的参数依然生效。举个例子:

var value = 2;
var foo = {
	value:1
};
function bar(name,age){
	this.habit = 'shopping';
	console.log(this.value,name,age);
}
bar.prototype.friend = 'ming';
var bindFoo = bar.bind(foo,'hong');
var obj = new bindFoo('18');
//undefined
//hong
//18
console.log(obj.habit);
console.log(obj.friend);
//shopping
//ming

尽管在全局和foo中都声明了value值,最后依然反悔了undefined,说明绑定的this失效了。

后文中new的模拟实现,就会知道这个时候的this已经指向了obj。

构造函数效果的优化实现

但是在这个写法中,我们直接将fBound.prototype = this.prototype,我们直接修改fBound.prototype的时候,也会直接修改绑定函数的prototype。这个时候,我们可以通过一个空函数来进行中转:

//第四版
Function.prototype.bind2 = function(context){
	var self = this;
	var args = Array.prototype.slice.call(arguments,1);
	var fNOP = function(){};
	var fBound = function(){
		var bindArgs = Array.prototype.slice.call(arguments);
		return self.apply(this instanceof fNOP ? this : context,args.concat(bindArgs));
	}
	fNOP.prototype = this.prototype;
	fBound.prototype = new fNOP();
	return fBound;
}

最终版

调用bind的不是函数时,提示错误:

if(typeof this !== "function"){
	throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}

最终代码为:

Function.prototype.bind2 = function (context){
	if(typeof this !== "function"){
		throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
	}
	var self = this;
	var args = Array.prototype.slice.call(arguments,1);
	var fNOP = function(){};
	var fBound = function(){
		var bindArgs = Array.prototype.slice.call(arguments);
		return self.apply(this instanceof fNOP?this : context,args.concat(bindArgs));
	}
	fNOP.prototype = this.prototype;
	fBound.prototype = new fNOP();
	return fBound;
}

最简化版:

Function.prototype.myBind = function(context){
//判断是否是undefined和null
	if(typeof context === 'undefined' || context === null){
		context = window;
	}
	self = this;
	return function(...args){
		return self.apply(context,args);
	}
}

好啦!说实话,写到这里我也还有点蒙,我先消化一下~
欢迎大家留言讨论!一起消化!

在这里插入图片描述

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

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

相关文章

在vue中深度选择器的使用

一、为什么要使用深度选择器 在vue中,当我们使用了第三方库中的组件时,想要更改一些样式,达到我们想要的效果,由于scoped的影响直接编写同名样式时,是覆盖不了组件内的样式的。 为了达到我们想要的效果,…

JavaSE基础50题:12. 编写代码模拟三次密码输入的场景。

概述 编写代码模拟三次输入的场景,最多能输入三次密码,密码正确,提示 “登录成功” ,密码错误,可重新输入,最多输入三次,三次均错,则提示退出程序。 代码 import java.util.Scann…

读者和写者问题

它可以解决的问题: 可以支持多个读者访问,通过count计数 来实现多个读者访问的时候是互斥的,不会出现不符合进程同步的问题:设置mutex互斥锁,保证count或count--和if Pv(mutex)是一气呵成的 读写公平,通过…

“分割“安卓用户,对标iOS,鸿蒙崛起~

近期关于**“华为于明年推出不兼容安卓的鸿蒙版本”**的消息传出,引起了业界的热议关注。自从2019年8月,美国制裁下,华为不再能够获得谷歌安卓操作系统相关付费服务,如此情况下,华为“备胎”鸿蒙操作系统一夜转正。 华…

如何掌握构建 LMS 网站的艺术

目录 什么是学习管理系统 (LMS) 在线课程和 LMS 网站的好处 为什么 WordPress 对于 LMS 网站很重要 统一学习中心 多功能性和可扩展性 提高教育参与度 简化管理和监控 节省时间和费用 技能评估和绩效监督 持续学习和技能提升 使用 WordPress 插件构建成功的 LMS 课程 专注于您的…

PyQt6 QDateEdit日期控件

​锋哥原创的PyQt6视频教程: 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计39条视频,包括:2024版 PyQt6 Python桌面开发 视频教程(无废话…

拨号连接bat命令和拨号错误623,系统无法找到此连接的电话簿项的解决方法

一、拨号bat命令 1、首先创建一个拨号连接,注意连接名称要使用英文 2、创建一个bat文件,里面内容 echo off chcp 65001rem 定义连接参数,第一个是用户名,第二个是密码 set usernameS11111111111 set passwords11111111111 set…

ORA-600 kcbzib_kcrsds_1一键恢复

一个19c库由于某种原因redo损坏强制打开库报ORA-600 kcbzib_kcrsds_1错误 SQL> startup mount pfile?/database/pfile.txt; ORACLE instance started. Total System Global Area 859830696 bytes Fixed Size 9034152 bytes Variable Size 5…

QT----Visual Studio打开.ui文件报错无法打开

问题 在我安装完qt后将它嵌入vs,后新建的文件无法打开ui文件 解决方法 右击ui文件打开方式,添加,程序找到你qt的安装目录里的designer.exe。点击确定再次双击就能够打开。

ES6中的继承,String类型方法的拓展

ES6中的继承: 主要是依赖extends关键字来实现继承,使用了extends实现继承不一定要constructor和super,因为没有的话会默认产生并调用它们。 在实现继承时,如果子类中有constructor函数,必须得在constructor中调用一下s…

linux搭建nacos集群

准备 检查是否安装jdk [roothao /usr/local/software/elk/logstash]# java -version java version "1.8.0_341" Java(TM) SE Runtime Environment (build 1.8.0_341-b10) Java HotSpot(TM) 64-Bit Server VM (build 25.341-b10, mixed mode)配置nacos 去github下载…

单片机语言--C51语言数据类型与存储类型以及C51的基本运算

单片机语言——C51语言 文章目录 单片机语言——C51语言一、 C51与标准C的比较二、 C51语言中的数据类型与存储类型2.1、C51的扩展数据类型2.2、数据存储类型 三、 C51的基本运算3.1 算术运算符3.2 逻辑运算符3.3 关系运算符3.4 位运算3.5 指针和取地址运算符 一、 C51与标准C的…

freeRtos队列的使用

一.队列的特性 队列是一个环形缓冲区 很多生产者生产很多数据,很多消费者读数据,唤醒之后首先是执行高优先级的,同等优先级先执行等待时间长的。 无论是写数据还是读数据都会有一个超时时间,写数据当队列已经满了就等待一会&…

HMMER学习——(待完善)

HMMER profile HMM files A HMMER profile file looks like this, with …’s marking elisions made for clarity and space: 1.全基因组基因家族的分析系列之HMMER3.1使用 2. hmmalign - align sequences to an HMM profile

vue3日常知识点学习归纳

1&#xff0c;父子组件传递&#xff1a; 父组件传递参数 <template><div><!-- 子组件 参数&#xff1a;num 、nums --><child :num"nums.num" :doubleNum"nums.doubleNum" increase"handleIncrease"></child>&l…

螺旋集污排气阀 微米级微泡排气除污装置螺旋除污器工作原理选型

​ 1&#xff1a;螺旋集污排气阀设备介绍 螺旋除污器&#xff0c;也被称为微泡排气除污装置&#xff0c;是一种有效的水处理设备&#xff0c;其主要功能是净化工作系统中的水。它的主要部分是螺旋管&#xff0c;能够脱除系统中的游离气体和微气泡。 螺旋管是由铜丝焊接制成的…

人工智能企业引入S-SDLC,推动安全能力大跃升,保障AI技术体系深化落地

某人工智能公司是国际知名的上市企业&#xff0c;核心技术处于世界前沿水平。多年来&#xff0c;该企业在智慧教育、智慧医疗、智慧城市、智慧司法、金融科技、智能汽车、运营商、消费者等领域进行深度技术赋能&#xff0c;深入推进各个行业的智能化、数字化转型建设。 人工智能…

解决思维题的一些自我总结

目录 常见思维题类型 排序 区间问题 01串串 字符串串 位运算 gcd 与 lcm 质数相关 二元组 常见思维题类型 思维题很多都可以说是贪心、但贪心种类很多&#xff0c;具体怎么贪&#xff0c;重要的还是在于积累经验吧...有些东西也很难总结&#xff0c;以下算是我的碎碎念…

正则表达式:深度解析与实用指南

目录 引言 正则表达式的基本概念 1. 字面量字符 2. 元字符 3. 量词 4. 分组和捕获 正则表达式的语法规则 1. 字符类 2. 转义字符 3. 锚点 4. 向前查找和向后查找 实际应用中的正则表达式技巧 1. 邮箱验证 2. URL 提取 3. 电话号码格式化 高级正则表达式技巧 1.…

阿里云 ACR 制品中心 AI/大数据镜像专场上新推荐榜

今天&#xff0c;AI 领域的快速发展不仅需要算法的突破&#xff0c;也需要工程的创新。随着容器技术和服务在企业的应用程度不断加深&#xff0c;企业对于容器的使用也越来越多地从在线业务逐渐向 AI、大数据类型的工作负载发展。同时&#xff0c;开发人员在考虑如何通过云原生…