简易模拟JS的Function对象的call、apply和bind方法
对 call 方法的简易模拟
1 Function.prototype._call = function(ctx) { 2 // 将函数自身设置为 ctx 对象的属性 3 // 非严格模式: 4 // - null 或 undefined 的this会自动指向全局对象 5 // - 基本类型的this会指向原始值的包装对象 6 ctx = ctx === null || ctx === undefined ? window : Object(ctx);
7 ctx.fn = this; 8 9 //// 执行该函数 10 const [, ...fnArgs] = [...arguments];
11 const result = ctx.fn(...fnArgs); 12 13 // 删除该对象上的函数属性 14 delete ctx.fn; 15 16 return result; 17 };
+ 另一个版本
function miniCall(ctx) { if (typeof this !== 'function') { throw new TypeError('调用call方法的对象应为函数!'); } ctx = (ctx === null || ctx === void 0) ? globalThis : Object(ctx); const args = [...arguments].slice(1); const key = Symbol('call.key'); ctx[key] = this; const result = ctx[key](...args); delete ctx[key]; return result; } Function.prototype._call = miniCall;
对 apply 方法的简易模拟
1 Function.prototype._apply = function(ctx, args) { 2 ctx = ctx === null || ctx === undefined ? window : Object(ctx);
3 ctx.fn = this; 4 5 let result; 6 7 if (Array.isArray(args)) { 8 result = ctx.fn(...args); 9 } else { 10 result = ctx.fn(); 11 } 12 13 delete ctx.fn; 14 15 return result; 16 };
对 bind 方法的简易模拟
1 // 1.基础性的模拟 2 Function.prototype._bind = function(ctx) { 3 if (typeof this !== 'function') { 4 throw new Error('Error: The bound object is not a function!'); 5 } 6 7 // 绑定this指向 8 const self = this; 9 // 获取绑定时的同步传参数 10 const [, ...args] = [...arguments]; 11 12 return function() { 13 return self.apply(ctx, [...args, ...arguments]); 14 }; 15 }; 16 17 18 // 2.考虑到将返回的绑定this的新函数作为构造函数的情景 19 Function.prototype._bind = function(ctx) { 20 if (typeof this !== 'function') { 21 throw new Error('Error: The bound object is not a function!'); 22 } 23 24 // 绑定this指向 25 const self = this; 26 // 获取绑定时的同步传参数 27 const [, ...args] = [...arguments]; 28 29 // 处理返回值被当作构造函数的case 30 //// 创建一个空函数(构造函数) 31 const F = function() {}; 32 //// 最终的返回值函数(内部区分this的指向) 33 const bound_fn = function() { 34 // 当作为构造函数时,this指向F的实例;当作为普通函数时this指向ctx 35 const pointer = this instanceof F ? this : ctx; 36 37 return self.apply(pointer, [...args, ...arguments]); 38 }; 39 //// 将F的原型指向被绑定函数的原型 40 F.prototype = this.prototype; 41 //// 将F的实例设为bound_fn的原型 42 bound_fn.prototype = new F(); 43 44 return bound_fn; 45 };
分类:
JavaScript
标签:
JavaScript
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?