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

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

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

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

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

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

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

  1. Function.prototype.myApply = function(obj){
  2.   if(typeof this !== 'function'){
  3.     console.error('type error!')
  4.   }
  5.   obj = obj || window;
  6.   obj.fn = this;
  7.   // 判断arguments[1]是否存在
  8.   if(arguments[1]){
  9.     result = obj.fn(...arguments[1]);
  10.   }else{
  11.     result = obj.fn();
  12.   }
  13.   delete obj.fn;
  14.   return result;
  15. }

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

  1. Function.prototype.myApply = function(obj){
  2.   if(typeof this !== 'function'){
  3.     console.error('type error!')
  4.   }
  5.   obj = obj || window;
  6.   obj.fn = this;
  7.   // 判断arguments[1]是否存在
  8.   if(arguments[1]){
  9.     result = obj.fn(...arguments[1]);
  10.   }else{
  11.     result = obj.fn();
  12.   }
  13.   delete obj.fn;
  14.   return result;
  15. }
  16. let dog = {   
  17.   name: '狗',   
  18.   eat(food1, food2) {     
  19.     console.log(this.name + '爱吃' + food1 + food2);   
  20.   }
  21. }
  22. let cat = {   
  23.   name: '猫',
  24. }
  25. dog.eat.apply(cat, ['鱼', '肉']); // 猫爱吃鱼肉
  26. 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. 创建SSH密钥时使用了自定义文件名遇到的问题

    问题描述 如图,我自定义了密钥文件名字. 所以在测试连接时导致了: 问题解决 连接的时候指定自己重命名的私钥文件名就好了. ssh -T -i git_test git@github.com SSH命 ...

  2. ListIterator特有的方法

    import java.util.ArrayList; import java.util.List; import java.util.ListIterator; /* 迭代 listIterator ...

  3. 深入Java微服务之网关系列1:什么是网关

    ​ 前言 近来,在想着重构一个新的产品.准备采用微服务的技术解决方案,来搭建基础设施框架.网关,是一个必不可少的组件.那么,网关到底是什么? 其又有什么特点或者特性,成为微服务必不可少的组件呢?今天, ...

  4. Ubuntu18 用新用户登录后退格键/方向键/制表键 乱码

    Ubuntu18新建用户后,用新用户登录,此时 退格键Backspace 变成了 ^H,且方向键.制表键.Del键等均失效 这样会造成很多的麻烦,解决方式有两种: 方式1:Ctrl + Backspa ...

  5. python小白记录三——pycharm+selenium搭建环境之 no module named 'selenium'异常解决

    在pycharm上搭建python+selenium自动化测试环境时,遇到一个很坑的问题:no moduel named 'selenium' 如下图: 1.查看你的python是否正确安装了sele ...

  6. windows设备相关位图与设备无关位图

    windows支持两种位图格式,DDB(device-dependent bitmap),DIB(device-independent bitmap).设备相关位图用于windows显示系统中,其图像 ...

  7. Solution -「SDOI 2018」「洛谷 P4606」战略游戏

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 个点 \(m\) 条边的无向连通图,\(q\) 次询问,每次给出一个点集 \(s\),求至少在原图中删去多 ...

  8. .NET Core Dto映射(AutoMapper)

    .Net Core Dto映射(AutoMapper) 我们假设一个场景, 采用EF Core+Web Api, 这时候可能会出现EF Core中的Entity Model和在项目中使用的Model之 ...

  9. ORACLE-创建用户和表空间

    /*分为四步 *//*第1步:创建临时表空间 */create temporary tablespace user_temp tempfile 'D:\oracle\oradata\Oracle9i\ ...

  10. const 和指针之间的姻缘

    const和指针到底有何姻缘呢? char const *p = NULL; //char const 和 const char 是一样的,p 是一个指向常整型的指针变量 ,指针变量的值不能改变 ch ...