JS基础面试题之手写bind

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;//考虑到绑定函数可能是有返回值的,加上returnreturn 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和nullif(typeof context === 'undefined' || context === null){context = window;}self = this;return function(...args){return self.apply(context,args);}
}

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

在这里插入图片描述

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

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

相关文章

【征稿倒计时十天】第三届高性能计算与通信工程国际学术会议(HPCCE 2023)

【有ISSN、ISBN号!!往届均已完成EI检索】 第三届高性能计算与通信工程国际学术会议(HPCCE 2023) 2023 3rd International Conference on High Performance Computing and Communication Engineering (HPCCE 2023) 2023年12月22-24日 | 中国哈尔滨 第三…

【LeetCode】2723. 两个 Promise 对象相加

两个 Promise 对象相加 题目题解 题目 给定两个 promise 对象 promise1 和 promise2,返回一个新的 promise。promise1 和 promise2 都会被解析为一个数字。返回的 Promise 应该解析为这两个数字的和。 示例 1: 输入: promise1 new Promise…

MySQL数据库,函数与分组

单行函数: 操作数据对象 接受参数返回一个结果 只对一行进行变换 每行返回一个结果 可以嵌套 参数也可以是一列或一个值 数值函数 基本函数: 注:ROUND(x,y)函数的y是负数时,即往高位进行四舍五入,如-3就是按百位…

创建vue项目:vue脚手架安装、vue-cli安装,vue ui界面创建vue工程(vue2/vue3),安装vue、搭建vue项目开发环境(保姆级教程二)

今天讲解 Windows 如何利用脚手架创建 vue 工程,以及 vue ui 图形化界面搭建 vue 开发环境,这是这个系列的第二章,有什么问题请留言,请点赞收藏!!! 文章目录 1、安装vue-cli脚手架2、vue ui创建…

UI自动化测试工具的定义及重要性

UI自动化测试工具在现代软件开发中起着不可或缺的作用。它们能够提高测试效率、减少人为错误、提供全面的测试覆盖,并支持持续集成。通过有效使用UI自动化测试工具,开发团队可以提高软件质量,提供更可靠的应用程序,满足用户的需求…

Java网络编程,使用UDP实现TCP(一), 基本实现三次握手

简介: 首先我们需要知道TCP传输和UDP传输的区别,UDP相当于只管发送不管对方是否接收到了,而TCP相当于打电话,需要进行3次握手,4次挥手,所以我们就需要在应用层上做一些功能添加,如:…

408——知识点大杂烩

在完成专业课的一轮复习以及历年真题的学习后,发现选择题甚至个别大题的考点就单纯考对概念的理解,会就是会,不会想到脑壳疼都做不出来,而408的知识点主打一个多杂,所以过来整理一下笔记。本文的知识点主要是在我做题过…

2002-2021年全国各地级市环境规制18个相关指标数据

2002-2021年全国各地级市环境规制18个相关指标数据 1、时间:2002-2021年 2、来源:城市年鉴 3、指标:行政区划代码、地区、年份、工业二氧化硫排放量(吨)、工业烟粉尘排放量(吨)、工业废水排放量(万吨)、工业废水排放达标量(万吨)、工业二氧…

dell服务器安装PERCCLI

因在linux 系统中无法查看系统磁盘的raid级别,也无法得知raid状态,需要安装额外的包来监控,因是dell服务器,就在dell网站中下载并安装 1、下载链接:驱动程序和下载 | Dell 中国https://www.dell.com/support/home/zh-…

互联网Java工程师面试题·RabbitMQ篇

目录 1、什么是 rabbitmq 2、为什么要使用 rabbitmq 3、使用 rabbitmq 的场景 4、如何确保消息正确地发送至 RabbitMQ? 如何确保消息接收方消费了消息? 5、如何避免消息重复投递或重复消费? 6、消息基于什么传输? 7、消息如…

设计模式基础——概述(1/2)

目录 一、设计模式的定义 二、设计模式的三大类别 三、设计模式的原则 四、主要设计模式目录 4.1 创建型模式(Creational Patterns) 4.2 结构型模式(Structural Patterns) 4.3 行为型模式(Behavioral Patterns&…

Java---线程讲解(二)

文章目录 1. Runnable接口2. 卖票案例3. 同步代码块解决数据安全问题4. 同步方法解决数据安全问题5. 线程安全的类6. Lock锁 1. Runnable接口 1. 创建线程的另一种方法是声明一个实现Runnable接口的类,之后重写run()方法,然后可以分配类的实例&#xff0…