js手写实现call、apply和bind方法

1call()方法

方法重用

使用 call() 方法,您可以编写能够在不同对象上使用的方法。

复制代码
//在Function原型上绑定全局自定义mycall方法
Function.prototype.mycall = function (obj) { const newthis = obj || this; //obj接收第一个参数,newthis可能是一个对象的this也可能是一个方法的this或者null,如果为null绑定调用者本身
newthis.fun = this; //此时的newthis为调用者需要改变this指向的目标,在其上面绑定调用者方法,即该方法的this也跟着改变了
 const [, ...arg] = arguments; //获取剩余参数
  const result = newthis.fun(...arg); //执行方法
  delete newthis.fun; //对象是引用传递,我们不能改变传进来的参数,所以我们要从传进来的参数身上把我们通过this绑定的方法删除掉。
  return result;
};

//测试
function a(str) { console.log(str, this.bb); } function b() { this.bb = 2; a.mycall(this, "aa"); } b();
复制代码

此时输出为: aa 2,即将b方法的bb获取到了,此时a方法的this指向为 function b,若将

a.mycall(this, "aa"); 改为 a.mycall(null, "aa"); 则输出为 aa undefined,此时this指向依旧是function a


2apply()方法

与call()方法用法完全一致, 唯一的区别就是参数的不同

function.apply(thisArg, arrayArgs)

thisArg: 在 function 函数运行时使用的 this 值
arrayArgs: 是一个参数数组

复制代码
Function.prototype.myapply = function (obj, args) {
  const newthis = obj || this;
  newthis.fun = this; 
  const result = newthis.fun(args); 
  delete newthis.fun;
  return result;
};

//测试
function a(arr) {
  console.log(arr, this.bb);
}
function b() {
  this.bb = 2;
  a.myapply(this, ["aa", "bb"]);
}
b();
复制代码

输出为  [ 'aa', 'bb' ] 2,参数为数组输出,与call存在参数传递的区别

 

3bind() 方法

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

和 call() 方法不同的是,call() 方法只会临时改变一次 this 指向,并立即执行,而 bind() 方法是返回一个 this 改变后的函数,并且不会立即执行。

复制代码
Function.prototype.mybind = function () {
  let that = this, //获取调用者
    args = arguments;
  return function () {
    //args[0]为调用者需要改变的this指向对象,内部使用apply方法返回一个新函数
    return that.apply(args[0], [...args].slice(1));
  };
};

function a() {
  console.log(this.name);
}
const o = {
  name: "张三",
};
const b = a.mybind(o); //函数b就是函数a的复制,只不过this指向了对象o
a();//undefined
b();//张三
复制代码

输出为undefined和张三,此时b为this指向O对象的a方法.

posted @   lijun12138  阅读(157)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示