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. 淘大大出了composer镜像 -- 给力

    composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

  2. abp vnext 调试

    在用Abp或者asp.net core 开发过程中,难免会遇到稀奇古怪的问题,需要对底层源代码进行调试,下面就教大家如何通过配置Visual Studio 2019来进行调试: 首先我们通过查看Abp ...

  3. 利用LNMP实现wordpress站点搭建

    一.部署MySQL 1.1 二进制安装mysql5.6 # 准备用户,依赖包,二进制程序 [root@nginx ~]# yum install -y libaio perl-Data-Dumper ...

  4. 一加6刷入kali nethunter

    Installing Kali NetHunter On the OnePlus 6 准备工具: adb: https://jingyan.baidu.com/article/22fe7cedf67e ...

  5. Kubernetes 集群日志 和 EFK 架构日志方案

    目录 第一部分:Kubernetes 日志 Kubernetes Logging 是如何工作的 Kubernetes Pod 日志存储位置 Kubelet Logs Kubernetes 容器日志格式 ...

  6. 基于6U CPCIe的TMS320C6678+KU060的信号处理板卡

    一.产品概述 基于6U CPCIe的C6678+KU060的信号处理板卡是新一代FPGA的高性能处理板卡.板卡采用一片TI DSP TMS320C6678和一片Xilinx公司 XCKU060-2FF ...

  7. TCP/IP详解 读书笔记(一):概述

    分层 网络协议通常分不同层次进行开发,每一层负责不同的职责,一个协议簇指的是一组不同层次上的多个协议的组合. TCP/IP通常被认为是一个四层协议系统: 链路层:主要是处理与电缆或其他传输媒介的物理接 ...

  8. Spring Boot 自动配置(基本配置)

    在关于Spring Boot的第一篇中就提到了其几大特性,其中关于Java配置简化属性注入在上一篇SpringBoot外部配置 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中已经介绍. ...

  9. python控制浏览器上传文件

    自动化爬虫方法和库很多,难点大多数在登录.可以大致分为:普通验证码,扫码登录,QQ一键登录,拖动验证,无痕验证,人工识别(比如12306登录) 万能大法可以破解一切以上需求,自动控制浏览器行为 参考文 ...

  10. DNS中的FQDN

    FQDN:(Fully Qualified Domain Name)全限定域名:同时带有主机名和域名的名称.(通过符号".") 例如:主机名是bigserver,域名是mycomp ...