手写实现call函数

115 阅读1分钟

call 函数介绍

  1. 作用: 改变this指向
  2. call存在位置:存在于函数的prototype(原型)

image.png

手写实现

  1. 在Function.prototype上添加myCall方法实现
  2. 改变this的指向
  3. 实现函数的正常调用
var name = 'global'
const a = {
      name: "a",
      getName: function () {
            // 指向 a对象(未改变指向之前)
            console.log(this.name);
      }

function c() {
      // 指向 window(未改变指向之前)
      console.log(this.name);

const b = {
      name: "b"

Function.prototype.myCall = function (context) {
      if (typeof this !=='function'){
            throw new Error("this is not Function")
      }
      // 取参数
      const args = [...arguments].slice(1)
      // 改变this指向
      context.fn = this
      // 调用方法
      const res = context.fn()
      // 消除方法
      delete context.fn
      return res
}
a.getName.myCall(b)
c.call(b,1,2)

运行结果

image.png

基于原理

1. this 指向问题

var name = 'global'
const a = {
      name: "a",
      getName: function () {
            // 指向 a对象(未改变指向之前)
            console.log(this);
      }

function c() {
      // 指向 window(未改变指向之前)
      console.log(this);

a.getName()
c()

运行结果

image.png

2. 函数赋值后this指向

var context = {
      name: 'Tom'
}
function a() {
      console.log(this);
}
context.fn = a
context.fn()

控制台输出赋值后的this指向

image.png