Handwritten bind, apply, call

1. Handwritten 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);

Insert picture description here

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

Insert picture description here

2. Handwriting apply:

The subsequent parameters passed by apply are in the form of an array (passing a single value will report an error)

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])

Insert picture description here

3. Handwritten 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);

Guess you like

Origin blog.csdn.net/qq_43812504/article/details/115017144