手写call/apply笔记

手写call和apply在面试题汇总里面还是挺常见的,这里记录下自己练习时候的笔记

手写call

call根据MDN解释,是传入this指向以及多个参数,执行之后返回结果,具体语法是function.call(thisArg, arg1, arg2, ...)。
thisArg:是传入的this指向
targ1, arg2, ...:传入的参数,call是可以传入多个
这里call有2种使用方法:

  1. foo.call() 此时没有传入新的this指向,那么默认为指向window,需注意严格模式下为undefined
  2. foo.call(a) 正常使用call,此时this指向为a
Function.prototype.myCall = function(context) {
  if(typeof this !== 'function') {
    // 判断当前调用者是否为函数
    return
  }
  // 保存传入的this指向,这里会出现没有传入this指向的问题,那么that就是默认的window
  that = context || window
  // 保存当前调用的函数
  that.fn = this
  // 通过slice来截取传入的参数
  const args = [...arguments].slice(1)
  // 传入参数调用函数
  const result = that.fn(...args)
  // 删除掉fn属性
  delete that.fn
  // 返回结果
  return result
}

实际测试手写call

// 当不传入或者传入undefined的时候,指向window
var test = function(){
  console.log(this===window);
}
test.myCall();//true
test.myCall(undefined);//true
// 借用别人的方法
var foo = {
  name:'day',
  sayName:function(){
    console.log(this.name);
  }
}
var bar={
  name:'Taec'
};
// 这里将this改为bar,那么输出的this.name的this就是bar
foo.sayName.myCall(bar); // Taec

// 实现继承
function Animal(name){   
  this.name = name;   
  this.showName = function(){   
    console.log(this.name);   
  }   
}   
 
function Dog (name){  
  // 使用call来借用构造函数完成继承
  // 这里的传参是直接传参
  Animal.myCall(this, name);  
}   
 
var dog = new Dog("dogdog");   
dog.showName(); //dogdog
手写call结果

手写apply

apply的原理和call一样,只是后面的传参是接收数组形式,具体语法func.apply(thisArg, [argsArray]),更多信息可以参考MDN。

Function.prototype.myApply = function(context) {
  if(typeof this !== 'function') {
    // 判断当前调用者是否为函数
    return
  }
  // 保存传入的this指向
  that = context || window
  // 保存当前调用的函数
  that.fn = this
  let result
  // 这里开始判断传入的参数是否存在,此时参数是一个数组形式[thisArg,[传参]]
  // 那么如果arguments[1]即传参存在的时候,就是需要传参调用保存的函数
  // 如果不存在就直接调用函数
  if (arguments[1]) {
    result = that.fn(...arguments[1])
  } else {
    result = that.fn()
  }
  return result
}

实际测试手写apply

// 当不传入或者传入undefined的时候,指向window
var test = function(){
  console.log(this===window);
}
test.myApply();//true
test.myApply(undefined);//true
// 借用别人的方法
var foo = {
  name:'day',
  sayName:function(){
    console.log(this.name);
  }
}
var bar={
  name:'Taec'
};
// 这里将this改为bar,那么输出的this.name的this就是bar
foo.sayName.myApply(bar); // Taec

// 实现继承
function Animal(name){   
  this.name = name;   
  this.showName = function(){   
    console.log(this.name);   
  }   
}   
 
function Dog (name){  
  // 使用call来借用构造函数完成继承
  // 这里需要注意,根据apply的使用,这里的传参是需要使用数组传参
  // 如果不是数组,那么输出的就是字符串的第一个字符
  Animal.myApply(this, [name]);  
}   
 
var dog = new Dog("dogdog");   
dog.showName(); //dogdog
手写apply结果
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容