js手撕——bind的模拟实现
在前端面试中,可能会出现一些手撕模拟实现的题目,这里进行一些记录。
原生api
js中中提供了 call, apply, bind
用于手动指定this的指向
概念
调用 call 和 apply 的对象,必须是一个函数 Function
由于apply()
方法(或者call()
方法)不仅绑定函数执行时所在的对象,还会立即执行函数
第一个参数,是一个对象, 由该对象调用Function
s.Function.call(obj)
// 相等于 obj.FunctionA.sayHello.call();//不传参数指向全局window对象,输出window.name也就是window
//如果call方法没有参数,或者参数为null或undefined,则等同于指向全局对象。
call 和 apply 的主要作用,是改变对象的执行上下文,并且是立即执行的。它们在参数上的写法略有区别。
bind 也能改变对象的执行上下文,它与 call 和 apply 不同的是,返回值是一个函数,并且需要稍后再调用一下,才会执行。
call(),apply(),bind()都是用来重定义this对象的
这三个函数的第一个参数都是 this 的指向对象;
第二个参数的差别:
call 的参数直接放进去,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,‘n1’, … ,‘n’ )。
apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,[‘n1’, …, ‘m’ ])。
bind 除了返回是函数以外,它的参数和 call 一样。
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!
var obj = {name:'tzb',age:18,myFunc:function(n, a){console.log(this.name + "年龄" + this.age);console.log(n + "年龄" + a);}
}var db = {name :'zhi',age:22
}
// call apply bind 都是挂到Object上的函数
//1.call
obj.myFunc(); // tzb 年龄18
// obj.myFunc().call()是错误写法 ()表示立即执行函数 myFunc()执行完成之后并没有返回值
obj.myFunc.call(db,'bin',33) // zhi年龄22 /n bin年龄33//2.apply
obj.myFunc.apply(db,['bin',33]) // zhi年龄22 bin年龄33//3.bind
var f = obj.myFunc.bind(db,'bin',33);
// bind返回的是一个函数 加上()才会执行
f(); // zhi年龄22 bin年龄33
模拟实现
bind的模拟实现使用到了 apply
,这里先给出apply
的模拟实现
apply
// args传入的需要是一个数组
function myApply(context, args) {if (typeof this !== 'function') {throw new Error('调用者必须是函数');}context = context || window;// 手动给调用者添加一个方法context.fn = this;let res;if (args) {res = context.fn(...args);}else {res = context.fn();}// 获得结果后删除该属性delete context.fn;return res;
}Function.prototype.myApply = myApply;
bind模拟实现
// bind(thisObj, a1, a2, a3);function myBind(...args) {if (typeof this !== 'function') {throw new Error('调用者必须是函数');}const fn = this;const context = args[0] || window;const myArgs = args.slice(1);return function(...newArgs) {fn.apply(context, myArgs.contact(newArgs));}}
上述模拟实现没有考虑bind返回的函数作为构造函数的情况。
在构造函数中,this指向新生成的对象。那么下面这个就不合适了。
return function(...newArgs) {fn.apply(context, myArgs.contact(newArgs));}
考虑构造函数的情况
// bind(thisObj, a1, a2, a3);function myBind(...args) {if (typeof this !== 'function') {throw new Error('调用者必须是函数');}// this为调用bind的函数对象const fn = this;const context = args[0] || window;const myArgs = args.slice(1);let Temp = function(){};Temp.prototype = fn.prototype;// bind返回的函数 f 作为构造函数时 let f = function(...newArgs) {return fn.apply(this instanceof f ? this : context, myArgs.contact(newArgs));}// 继承原型链上的属性f.prototype = new Temp();return f;}
js手撕——bind的模拟实现相关推荐
- 常见js手撕题及算法总结
文章目录 实现一下观察者模式 实现一下工厂模式 实现一下单例模式 设计一个lazyMan,实现以下功能: 实现一个简单的EventEmitter 手撕实现原生js的一些方法(call.apply.bi ...
- 前端百题斩【015】——快速手撕call、apply、bind
写该系列文章的初衷是"让每位前端工程师掌握高频知识点,为工作助力".这是前端百题斩的第15斩,希望朋友们关注公众号"执鸢者",用知识武装自己的头脑. 在百题斩[ ...
- (面试题)面试官为啥总是让我们手撕call、apply、bind?
引言 上一篇关于<面试官为啥总是喜欢问前端路由实现方式>的文章发布后,发现还是挺受欢迎的.这就给我造成了一定的困惑 之前花了很长时间,实现了一个自认为创意还不错的关于前端如何利用node+ ...
- 前端date format_前端面试-手撕代码篇
前言 在前端面试有一个非常重要的环节,也是面试者最担心的一个环节.对"手撕代码"的考察需要面试者平时总结和积累(临时抱佛脚是不好使的),在这里笔者就自己如何攻破"手撕代码 ...
- Python3《机器学习实战》学习笔记(八):支持向量机原理篇之手撕线性SVM
原 Python3<机器学习实战>学习笔记(八):支持向量机原理篇之手撕线性SVM 置顶 2017年09月23日 17:50:18 阅读数:12644 转载请注明作者和出处: https: ...
- 和12岁小同志搞创客开发:手撕代码,做一款声控灯
机缘巧合在网上认识一位12岁小同志,从零开始系统辅导其创客开发思维和技巧. 项目专栏:https://blog.csdn.net/m0_38106923/category_11097422.html ...
- 手撕 MySQL 事务,发生了什么?
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:2 个月的面试亲身经历告诉大家,如何进入大厂? 作者:flyman 链接:https://segmentfaul ...
- python 遍历_Python手撕广度优先遍历
在谈广度优先遍历之前,我们需要知道图是什么. 1.图 图(graph)是表示物件与物件之间关系的数学对象,是图论的基本研究对象,图由节点(node)和边(edge)组成.图分为两种:1.有向图.2. ...
- 猿人学第二题,手撕OB混淆给你看(step06-控制流平坦化)
前情回顾: 猿人学第二题,手撕OB混淆给你看(Step1-开篇) 猿人学第二题,手撕OB混淆给你看(step2-字符串数字回填) 猿人学第二题,手撕OB混淆给你看(step3-函数调用还原) 猿人学第 ...
最新文章
- Ubuntu root密码设置
- 计算机的硬盘和光盘数,硬盘和光盘属于什么媒体
- 由浅入深:自己动手开发模板引擎——置换型模板引擎(一)
- 用神经网络分类响尾蛇和牛蛙
- SQL Server 2014 Win7 Win10 安装详解 SQL Server 2017 2019 Linux及SQL TSQL ETL实用案例
- java treemap_Java TreeMap keySet()方法与示例
- java 执行顺序混乱_java类执行顺序问题
- 包含贴息时如何重算还款计划
- 编程学习好去处:35 个快速学习的编程网站
- mongodb(分片)
- [复变函数]第16堂课 4.4 解析函数零点的孤立性及惟一性定理
- SpringBoot整合Sharding-JDBC实现水平分库分表之操作公共表
- 前端如何使用mock模拟接口数据
- 最美的公式:你也能懂的麦克斯韦方程组
- Android EditText身份证等类型
- NET 3行代码实现文字转语音功能
- 如何应对redis缓存的击穿、穿透和雪崩
- 卷积神经网络 神经网络,卷积神经网络基础知识
- java swing桌面程序打包成.exe文件
- atan函数和atan2函数的区别