call,apply,bind,以及手写实现

98 阅读1分钟

call和apply

语法:

在这里插入图片描述

只是传参不一样

只是传参不一样

这样animal调用this实际上这个this时a函数

特点:

1.函数调用的call就代表这个函数执行了不用在执行他

2.调用 call 和 apply 指向 undefined 或者 null ,会将 this 指向 window。

3.调用 call 和 apply 指向一个值类型, 会将 this 指向由它们的构造函数创建的实例。

在这里插入图片描述

图片来自:juejin.cn/post/703075…

bind

语法

在这里插入图片描述

特点:

bind调用后不会执行函数

手写call

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
</body>

</html>
<script>
  Function.prototype.mycall = function (ctx, ...args) {
      // 判断上下文类型 如果是undefined或者 null 指向window
  // 否则使用 Object() 将上下文包装成对象
  const o = ctx == undefined ? window : Object(ctx)
  // 如何把函数foo的this 指向 ctx这个上下文呢
  // 把函数foo赋值给对象o的一个属性  用这个对象o去调用foo  this就指向了这个对象o
  // 下面的this就是调用_call的函数foo  我们把this给对象o的属性fn 就是把函数foo赋值给了o.fn
  //给context新增一个独一无二的属性以免覆盖原有属性
  const key = Symbol()
  o[key] = this
  // 立即执行一次
  const result = o[key](...args)
  // 删除这个属性
  delete o[key]
  // 把函数的返回值赋值给_call的返回值
  return result
  }

  function animal(name, age) {
    this.anname = name
    this.age = age
  }
  function a() {e
  }
  animal.mycall(a,"小红",222)
  console.log(a.anname );
  console.log(a.age );

</script>

代码参照:juejin.cn/post/703075…

手写apply

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
</body>

</html>
<script>
  Function.prototype.myapply = function (ctx, args = []) {
      // 判断上下文类型 如果是undefined或者 null 指向window
  // 否则使用 Object() 将上下文包装成对象
  const o = ctx == undefined ? window : Object(ctx)
  // 如何把函数foo的this 指向 ctx这个上下文呢
  // 把函数foo赋值给对象o的一个属性  用这个对象o去调用foo  this就指向了这个对象o
  // 下面的this就是调用_call的函数foo  我们把this给对象o的属性fn 就是把函数foo赋值给了o.fn
  //给context新增一个独一无二的属性以免覆盖原有属性
  const key = Symbol()
  o[key] = this
  // 立即执行一次
  const result = o[key](...args)
  // 删除这个属性
  delete o[key]
  // 把函数的返回值赋值给_call的返回值
  return result
  }

  function animal(name, age) {
    this.anname = name
    this.age = age
  }
  function a() {
  }
  animal.myapply(a,["小红",222])
  console.log(a.anname );
  console.log(a.age );

</script>

就改一下参数就可以

代码参照:juejin.cn/post/703075…

在这里插入图片描述

手写bind

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
</body>

</html>
<script>
  Function.prototype.mybind = function (ctx, ...args) {
    // 下面的this就是调用_bind的函数,保存给_self
    const _self = this
    return function (...arg2) {
      return _self.apply(ctx, [...args, ...arg2]); // 注意参数的处理
    }
  }

  function animal(name, age) {
    this.anname = name
    this.age = age
  }
  function a() {
  }
  animal.mybind(a, "小红", 222)()
  console.log(a.anname);
  console.log(a.age);

</script>