关于call的使用和原理分析

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

注意:该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组

var obj = {
  a: 1,
  b: function () {
    console.log(this.a)
  }
}
window.a = 100
var b = obj.b;
b() // 100
b.call(obj) // 1

语法

function.call(thisArg, arg1, arg2, ...)

参数

thisArg

可选的。在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。

var obj = {
  a: 1,
  b: function () {
    console.log(this.a)
  }
}
window.a = 100
var b = obj.b;
b.call(null) // 100

arg1, arg2, ...

指定的参数列表。

原理

Function.prototype.myCall = function myCall (...args) {
  var ary = args.slice(1)
  if (args[0] == undefined) {
    this(...ary)
  } else {
    var obj = Object(args[0])
    obj.__proto__.fn = this
    obj.fn(...ary)
    delete obj.__proto__.fn
  }
  return this
}

分析

var obj = Object(args[0])

使用 Object 构造函数创建一个对象包装器。当以非构造函数形式被调用时,Object 等同于 new Object()。

obj 表示函数运行时传入的 this 值,如果基本数据类型会先转换成引用数据类型。因为 this 值必须是对象的形式。

obj.__proto__.fn = this;
obj.fn(...ary)
delete obj.__proto__.fn

fn 是定义在运行时传入的 this 值上的一个属性。this 表示需要改变 this 指向的函数

关于__proto__这个连接存在于实例与构造函数的原型对象之间,那么有人会问为什么要设置在__proto__上,而不设置在实例的prototype上,因为有可能是普通对象或者是函数,普通对象是没有prototype属性的。

通过运行时传入的 this 值来调用 fn 函数。那么 fn 函数里面的 this 就自然是运行时传入的 this 值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值