手写bind、apply、call

bind、apply、call的使用:

function print(age){
  console.log(this.name +''+this.sex+''+age);
}

print.call({name:'xx',sex:'女'},1,2,3);
print.call({name:'xx',sex:'女'},[1,2,3]);

// apply只能是数组传参
print.apply({name:'xx',sex:'女'},[1,2,3]);

//bind函数会返回一个函数,我们想要调用的时候才会执行
let fu1 = print.bind({name:'xx',sex:'女'},[1,2,3]);
fu1();
let fu2 = print.bind({name:'xx',sex:'女'},1,2,3);
fu2();


let fu3 = print.bind({name:'xx',sex:'女'},1,2,3);
//将返回的函数用作构造函数,this指针指向他的实例
let fu4 = new fu3();
console.log(fu4);

依次输出:
在这里插入图片描述

1.手写bind:

Function.prototype.myBind = function () {
  if (typeof this != 'function') {
    throw new TypeError('ERROR');
  }
  //获取传递的参数
  //Array.from()
  //1.复制数组,如果传的是数组,将把数组复制一份传给新数组。
  //2.如果是伪数组,将会转成数组在赋给新数组。
  // 获取参数
  const args = Array.from(arguments);
  //要改变的this指向
  const target = args.shift();
  console.log('目标this',target);//{ name: 'xx' }
  console.log('其余参数',args);//[ 1, 2, 3 ]
  //调用它的函数
  const self = this;
  //返回一个函数
  return function F() {
    // 因为返回的这个函数,我们可以 new F(),所以需要判断 
    if (this instanceof F) {
    	console.log('...',...args)
     // 对于 new 的情况来说,不会被任何方式改变 this 
      return new self(...args);
    } else {
      return self.apply(target,args)
    }
  }
}

// 普通函数 
function print() {
  console.log('this中的name',this.name);
}


let F = print.myBind({ name: 'xx'}, 1, 2, 3);
// 返回对象 
let obj1 = F(); 
console.log(obj1);

// let obj2 = new F();
// console.log('obj2',obj2);

在这里插入图片描述

 let obj2 = new F();
 console.log('obj2',obj2);

在这里插入图片描述

2.手写apply:

apply 后续传递的参数是数组形式(传单个值会报错)

Function.prototype.myApply = function(context){
  if (typeof this !== 'function'){
    throw new TypeError('ERROR');
  }
  console.log(context);//要更改的this指向
  context = context || window;
  
  console.log(this)
  context.fn = this;//新增fn属性,将值设置为调用apply的函数

  let result;
  //判断是否有参数
  if(arguments[1]){
    console.log(...arguments[1]);
    result = context.fn(...arguments[1]);
  }else{
    result = context.fn();
  }
  delete context.fn
  return result;
}

// 普通函数 
function print(age,age2,age3){ console.log(this.name+" "+ age + " "+ age2+" "+age3); }
// 自定义对象 
var obj = { name:'xx' }

print.myApply(obj,[1,2,3])

在这里插入图片描述

3.手写call:

Function.prototype.myCall = function (context) {
  if (typeof this != 'function') {
    throw new TypeError('Error');
  }
  context = context || window;
  const args = Array.from(arguments).slice(1);
  context.fn = this;
  let result = context.fn(...args);
  delete context.fn;
  return result;

}

function print(age){
  console.log(this.name +''+age);
}
print.myCall({name:'xx'},1,2,3);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值