bind、call实现原理

本文深入探讨了JavaScript中的bind方法,解释了它如何绑定函数的this值,并允许预设函数调用的参数。此外,还通过代码示例展示了bind的实现原理。同时,文章还对比了bind与call的使用区别。最后,提供了call的自定义实现,进一步理解其工作方式。
摘要由CSDN通过智能技术生成

释义

bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()中的第一个参数的值,剩下的参数以逗号分隔,与call的传参数一样

bind用法

var person = {
    name: '妖怪'
}

function other (age, sex) {
    console.log(this.name + '的年龄是' + age + ',性别:' + sex)
}

// 注意bind使用时必用在结尾用()执行,注意与call、apply的区别
other.bind(person, 21, '男')() // 妖怪的年龄是21,性别:男
other.bind(person, 21)('男') // 妖怪的年龄是21,性别:男,也可以在调用时再次传入参数

原理代码

Function.prototype.mybind = function () {
  var that = this // 保存原this指向
  // 这里用Array.prototype.shift.call的方法把类数组对象arguments参数转化为数组,同时用shift方法提取第一个参数作为新的上下文this;
  var context = Array.prototype.shift.call(arguments)
  
  // 因为shift方法会改变原数组,所以args为剩余的参数,并转化为数组
  var args = Array.prototype.slice.call(arguments)
  
  // return为bind()的返回值,还没有进行调用
  return function () {
  
    // 以下为bind(a,b,c)(d)进行调用,新的this上下文context当作第一个参数传入,余下的为剩余的参数,此时的arguments为调用时的入参,用concat进行合并
    that.apply(context, Array.prototype.concat.call(args, Array.prototype.slice.call(arguments)))
  }
}

var person = {
    name: '妖怪'
}

function other (age, sex) {
    console.log(this.name + '的年龄是' + age + ',性别:' + sex)
}

other.mybind(person, 21, '男')() // 妖怪的年龄是21,性别:男
other.mybind(person, 21)('男') // 妖怪的年龄是21,性别:男

附:call实现原理

Function.prototype.myCall = function(context, ...args) { // 解构context 与arguments
  if(typeof this !== 'function') { // this 必须是函数
    throw new TypeError(`It's must be a function`)
  }
  if(!context) context = window; // 没有context,或者传递的是 null undefined,则重置为window
  const fn = Symbol(); // 指定唯一属性,防止 delete 删除错误
  context[fn] = this; // 将 this 添加到 context的属性上
  const result = context[fn](...args); // 直接调用context 的 fn
  delete context[fn]; // 删除掉context新增的symbol属性
  return result; // 返回返回值
}

var bar = {a: 1}
function foo(b) {
  console.log(this.a + b)
  return this.a+b
} 
foo.myCall(bar, 2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值