apply()函数,在功能上类似于call(),只是传递参数的格式有所不同。

dog.eat.call(cat, '鱼', '肉');
dog.eat.apply(cat, ['鱼', '肉']);

因此我们完全可以套用 '上一篇对call()的分析‘,得到下列代码。

Function.prototype.myApply = function(obj){
  // 判断调用对象是否为函数
  if(typeof this !== 'function'){
    console.error('type error!')
  }
  // 判断绑定的对象
  obj = obj || window;
  obj.fn = this;
  // 将执行结果保存并返回
  let result = obj.fn();
  // 删除context.fn属性
  delete obj.fn;
  return result;
}

最后考虑下方法中使用的参数(是传递过来的第二个参数),并且格式就是数组,可以之间使用。

Function.prototype.myApply = function(obj){
  if(typeof this !== 'function'){
    console.error('type error!')
  }
  obj = obj || window;
  obj.fn = this;
  // 之间使用传递过来的数组
  let result = obj.fn(...arguments[1]);
  delete obj.fn;
  return result;
}

当没有数组传递过来的时候,arguments[1]获取不到,会报错,因此要再加一层判断。

Function.prototype.myApply = function(obj){
  if(typeof this !== 'function'){
    console.error('type error!')
  }
  obj = obj || window;
  obj.fn = this;
  // 判断arguments[1]是否存在
  if(arguments[1]){
    result = obj.fn(...arguments[1]);
  }else{
    result = obj.fn();
  }
  delete obj.fn;
  return result;
}

最后通过一个例子,来验证是否达到apply()的功能要求。

Function.prototype.myApply = function(obj){
  if(typeof this !== 'function'){
    console.error('type error!')
  }
  obj = obj || window;
  obj.fn = this;
  // 判断arguments[1]是否存在
  if(arguments[1]){
    result = obj.fn(...arguments[1]);
  }else{
    result = obj.fn();
  }
  delete obj.fn;
  return result;
}
let dog = {   
  name: '狗',   
  eat(food1, food2) {     
    console.log(this.name + '爱吃' + food1 + food2);   
  }
}
let cat = {   
  name: '猫',
}
dog.eat.apply(cat, ['鱼', '肉']); // 猫爱吃鱼肉
dog.eat.myApply(cat, ['鱼', '肉']); // 猫爱吃鱼肉

另外两篇:'对apply()函数的分析' 和 '对bind()函数的分析' 。

理解并手写 apply() 函数的更多相关文章

  1. 理解并手写 call() 函数

    手写自己的call,我们要先通过call的使用,了解都需要完成些什么功能? call()进行了调用,是个方法,已知是建立在原型上的,使用了多个参数(绑定的对象+传递的参数). 我们把手写的函数起名为m ...

  2. 理解并手写 bind() 函数

    有了对call().apply()的前提分析,相信bind()我们也可以手到擒来. 参考前两篇:'对call()函数的分析' 和 '对apply()函数的分析',我们可以先得到以下代码: Functi ...

  3. WPF启动流程-自己手写Main函数

    WPF一般默认提供一个MainWindow窗体,并在App.Xaml中使用StartupUri标记启动该窗体.以下通过手写实现WPF的启动. 首先先介绍一下VS默认提供的App.Xaml的结构,如下图 ...

  4. 前端面试题整理——手写bind函数

    var arr = [1,2,3,4,5] console.log(arr.slice(1,4)) console.log(arr) Function.prototype.bind1 = functi ...

  5. python 精华梳理(已理解并手写)--全是干货--已结

    基础部分 map,reduce,filter,sort,推导式,匿名函数lambda , 协程,异步io,上下文管理 自定义字符串转数字方法一不使用reduce import re def str2i ...

  6. 手写bind函数

    实现bind函数 参考MDN提供的Polyfill方案 Function.prototype.myBind = function(context){ //这里对调用者做一个判断,如果不是函数类型,直接 ...

  7. C++之手写strlen函数

    代码: int strlen(const char *str){ assert(str!=NULL); intlen=; while((*str++)!='\0') len++; return len ...

  8. js面试题之手写节流函数和防抖函数

    函数节流:不断触发一个函数后,执行第一次,只有大于设定的执行周期后才会执行第二次 /* 节流函数:fn:要被节流的函数,delay:规定的时间 */ function throttle(fn,dela ...

  9. 常见的JS手写函数汇总(代码注释、持续更新)

    最近在复习面试中常见的JS手写函数,顺便进行代码注释和总结,方便自己回顾也加深记,内容也会陆陆续续进行补充和改善. 一.手写深拷贝 <script> const obj1 = { name ...

随机推荐

  1. linux中vim编辑器三种模式及常用命令的使用

    Linux命令经常使用才会烂熟于心 命令行模式: 移动光标: 向下左右箭头可以移动光标: 将光标移动到行尾:$; 将光标移动到行头:^: 将光标移动到页尾:shift+g; 将光标移动到页头:1+sh ...

  2. LaunchScreen原理

    会自动加载LaunchScreen是因为在Target当中,指定了Launch Screen file 它的底层实现其实把LaunchScreen上的东西,生成了一张图片,然后把这张图片设为程序的启动 ...

  3. Loadrunner 11 中的Java Vuser

    Java vuser是自定义的java虚拟用户脚本,脚本中可以使用标准的java语言. 1.安装jdk 注意,lr11最高支持jdk1.6 2.配置环境变量 3.在lr中选择java vuser协议 ...

  4. Shell for&while中的循环

    #!/usr/bin/ksh #数字段形式 for i in {1..10} do echo $i done #详细列出(字符且项数不多) for File in 1 2 3 4 5 do echo ...

  5. HMS Core 能力速配,唱响恋爱进行曲

    情人节,HMS Core 最具CP感的能力搭档来袭,浓浓爱意,表白各行业,你准备好了吗? 1.ML Kit +Signpal Kit 科技相助,恋爱提速.展现爱意的方式有千百种,你可以用文本翻译学习数 ...

  6. CSS3自定义滚动条样式-webkit内核

    自定义滚动条实现 此部分针对webkit内核的浏览器,使用伪类来改变滚动条的默认样式,详情如下: 滚动条组成部分 1. ::-webkit-scrollbar 滚动条整体部分 2. ::-webkit ...

  7. Docker名词解释

    http://www.runoob.com/docker/docker-architecture.html  

  8. treevalue——Master Nested Data Like Tensor

    首先,请和我一起高呼--"treevalue--通用树形结构建模工具 + 极简树形结构编程模型". 咳咳,好久没更新了,这一次是真的好久不见,甚是想念.在之前的三期中,关于 tre ...

  9. Welcom to my studyspace! 欢迎来到我的学习空间!

    由于新手,博客才刚开始起步,用于记录我的学习,博客的建设后续需要将其完善 对我的博客进行diy 用于分享我的学习经历,一些笔记,还有一些小小的心得

  10. 施耐德NOE77101后门漏洞分析

    固件下载地址: GitHub - ameng929/NOE77101_Firmware 文件目录结构,这里只列出了一些主要的文件信息: ├── bin ├── ftp ├── fw ├── rdt ├ ...