简易模拟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 };

 

posted @ 2021-11-30 12:05  樊顺  阅读(63)  评论(0)    收藏  举报