call、apply、bind的源码实现
2021/5/23 20:27:14
本文主要是介绍call、apply、bind的源码实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
根据B站的小野森森老师的视频整理,代码有所修改。
主要有以下难点:
- 怎样改变
this
指向 - 怎样给修改后的函数传参
解决方法是:函数内部的this
指向是通过其调用者决定的,因此可以通过将call
等的第一个参数(假设为ctx
)上增加一个属性(假设为originFn
),保存当前调用函数的地址,通过调用ctx.originFn
来改变this
指向。然后通过将其余参数拼接为字符串,调用eval
方法将字符串转为表达式的方式传参。
源码如下:
1、call
// call Function.prototype.myCall = function (ctx) { ctx = ctx == null ? window : Object(ctx); var args = []; for (var i = 1; i < arguments.length; i++) { args.push("arguments[" + i + "]"); } var originFn = new Date().getTime(); // 保证不重名 ctx.originFn = this; var ret = eval("ctx.fn(" + args + ")"); delete ctx.originFn ; return ret; }
2、apply
// apply Function.prototype.myApply = function (ctx, args) { if (typeof args !== "object" && typeof args !== "function") { throw new TypeError("CreateListFromArrayLike called on non-object"); } args = [].slice.call(args); ctx = ctx == null ? window : Object(ctx); var _args = []; for (var i = 0; i < args.length; i++) { _args.push("args[" + i + "]"); } var originFn = new Date().getTime(); // 保证不重名 ctx.originFn = this; var ret = eval("ctx.fn(" + _args + ")"); delete ctx.originFn ; return ret; }
3、bind
// bind Function.prototype.myBind = function (ctx) { var args = [].slice.call(arguments, 1), _tempFn = function () { }, originThis = this; var newFn = function () { var newArgs = [].slice.call(arguments); // 这里需要判断返回的函数是不是使用new调用的,如果是,则需要保证把这个函数当作普通的构造函数使用,不能改变其内部this为ctx,并且生成的实例需要继承调用bind的函数 return originThis.apply(this instanceof newFn ? this : ctx, args.concat(newArgs)); } _tempFn.prototype = this.prototype; newFn.prototype = new _tempFn(); return newFn; }
[参考链接]
[1]、小野森森老师的视频
这篇关于call、apply、bind的源码实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-30uniAPP 实现全屏左右滚动滚动的效果-icode9专业技术文章分享
- 2024-06-30如何在本地使用授权或插件-icode9专业技术文章分享
- 2024-06-30伪静态规则配置方法汇总-icode9专业技术文章分享
- 2024-06-29易优CMS安装常见问题汇总-icode9专业技术文章分享
- 2024-06-28易优新手必读安装教程-icode9专业技术文章分享
- 2024-06-28忘记eyoucms后台密码怎么办?-icode9专业技术文章分享
- 2024-06-26终极指南:Scrum中如何设置需求优先级
- 2024-06-26AI大模型企业应用实战(25)-为Langchain Agent添加记忆功能
- 2024-06-26小白家庭 nas 搭建方案-icode9专业技术文章分享
- 2024-06-23AI大模型企业应用实战(14)-langchain的Embedding