js【详解】bind()、call()、apply()( 含手写 bind,手写 call,手写 apply )

简介: js【详解】bind()、call()、apply()( 含手写 bind,手写 call,手写 apply )

必备知识点:js 【详解】函数中的 this 指向_js function this-CSDN博客

https://blog.csdn.net/weixin_41192489/article/details/123093256

bind、call、apply 的相同点

  • 都是Function原型上的方法
  • 用途都是改变 this 的指向
  • 第一个参数都是新的 this

bind、call、apply 的不同点

  • bind 会返回一个新的函数,目标函数在新函数调用时才会执行
let newFunc = obj.myFn.bind(newObj,'北京','上海');
newFunc();
  • call 的传参方式与bind相同(第2-N个参数用,分隔),但目标函数会立即执行
obj.myFn.call(newObj,'北京','上海')
  • apply 只有两个参数,第一个参数是新的 this,第二个参数是由目标函数的传参构成的数组
obj.myFn.apply(newObj,['北京','上海'])

使用范例

var name="张三",age=18;

var obj = {
  name:"李四",
  oldAge:this.age,
  myFn:function(a, b){
    console.log( this.name+"年龄"+this.age,"来自"+a+"去往"+b )
  }
}

var newObj = {
    name:"王五",
    age:22
}

obj.myFn.call(newObj,'北京','上海'); // 王五年龄22 来自北京去往上海
obj.myFn.apply(newObj,['北京','上海']);  // 王五年龄22 来自北京去往上海 
obj.myFn.bind(newObj,['北京','上海'])(); //王五年龄22 来自北京,上海去往undefined
obj.myFn.bind(newObj,'北京','上海')(); // 王五年龄22 来自北京去往上海


手写 bind

// 手写 bind
Function.prototype.my_bind = function () {
  // 将参数拆解为数组
  const argList = Array.prototype.slice.call(arguments);

  // 获取参数的第一项,并将参数的第一项从参数数组中移除
  const first_arg = argList.shift();

  // 返回一个函数
  return () => {
    // 箭头函数中的this继承函数外的this
    return this.apply(first_arg, argList);
  };
};

还可以参考下文的手写 apply 进行更深度的改写(不使用apply)

手写 call

// 手写 call
Function.prototype.my_call = function () {
  // 将参数拆解为数组
  const argList = Array.prototype.slice.call(arguments);

  // 获取参数的第一项,并将参数的第一项从参数数组中移除
  const first_arg = argList.shift();

  // 返回函数执行的结果
  return this.apply(first_arg, argList);
};

还可以参考下文的手写 apply 进行更深度的改写(不使用apply)

手写 apply

// 手写 apply
Function.prototype.my_apply = function (new_this, argArray) {
  if (new_this !== null && new_this !== undefined) {
    // 第一个参数不是 null 和 undefined 时,将其转换为对象
    new_this = Object(new_this);
  } else {
    // 第一个参数是 null 或 undefined 时,将其重置为 window
    new_this = window;
  }
  // 若第二个参数没有传 argArray ,则重置为空数组
  argArray = argArray || [];

  // 使用 Symbol 生成一个唯一的属性,避免覆盖 new_this 中的已有属性
  const key = Symbol("fn");

  // 将原this(即原函数)变为新this(即传入的new_this) 的方法
  new_this[key] = this;

  // 将原函数作为新this的对象方法执行,实现函数内 this 的指向变为 新this
  const result = new_this[key](...argArray);

  // 移除新增的方法
  delete new_this[key];

  // 返回函数执行的结果
  return result;
};


目录
相关文章
|
28天前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
26 1
|
2月前
|
JavaScript 前端开发
JS高级—call(),apply(),bind()
【10月更文挑战第17天】call()`、`apply()`和`bind()`是 JavaScript 中非常重要的工具,它们为我们提供了灵活控制函数执行和`this`指向的能力。通过合理运用这些方法,可以实现更复杂的编程逻辑和功能,提升代码的质量和可维护性。你在实际开发中可以根据具体需求,选择合适的方法来满足业务需求,并不断探索它们的更多应用场景。
14 1
|
2月前
|
JavaScript 前端开发
js 中call()和apply()
js 中call()和apply()
31 1
|
3月前
|
自然语言处理 JavaScript 前端开发
JS中this的应用场景,再了解下apply、call和bind!
该文章深入探讨了JavaScript中`this`关键字的多种应用场景,并详细解释了`apply`、`call`和`bind`这三个函数方法的使用技巧和差异。
|
7月前
|
JavaScript 前端开发
javascript中的call和apply
javascript中的call和apply
|
7月前
|
JavaScript 前端开发
JavaScript中call()与apply()的作用与区别?
JavaScript中call()与apply()的作用与区别?
|
4月前
|
前端开发 JavaScript 开发者
揭秘JavaScript魔法三剑客:call、apply、bind,解锁函数新世界,你的前端之路因它们而精彩!
【8月更文挑战第23天】在 JavaScript 的世界里,`call`、`apply` 和 `bind` 这三个方法常常让新手感到困惑。它们都能改变函数执行时的上下文(即 `this` 的指向),但各有特点:`call` 接受一系列参数并直接调用函数;`apply` 则接收一个参数数组,在处理不确定数量的参数时特别有用;而 `bind` 不会立即执行函数,而是创建一个新版本的函数,其 `this` 上下文已被永久绑定。理解这三个方法能帮助开发者更好地运用函数式编程技巧,提升代码灵活性和可维护性。
41 0
|
3月前
|
JavaScript 前端开发
this指向的几种情况以及js简单实现call、apply、bind___六卿
本文讨论了JavaScript中`this`的指向规则,并提供了`call`、`apply`和`bind`方法的简单实现,用于改变函数的`this`指向。
20 0
this指向的几种情况以及js简单实现call、apply、bind___六卿
|
3月前
|
JavaScript
js的this与call,apply,bind
js的this与call,apply,bind
|
4月前
|
JavaScript 前端开发
js 中call()和apply()
js 中call()和apply()
39 0