理解并手写 apply() 函数
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() 函数的更多相关文章
- 理解并手写 call() 函数
手写自己的call,我们要先通过call的使用,了解都需要完成些什么功能? call()进行了调用,是个方法,已知是建立在原型上的,使用了多个参数(绑定的对象+传递的参数). 我们把手写的函数起名为m ...
- 理解并手写 bind() 函数
有了对call().apply()的前提分析,相信bind()我们也可以手到擒来. 参考前两篇:'对call()函数的分析' 和 '对apply()函数的分析',我们可以先得到以下代码: Functi ...
- WPF启动流程-自己手写Main函数
WPF一般默认提供一个MainWindow窗体,并在App.Xaml中使用StartupUri标记启动该窗体.以下通过手写实现WPF的启动. 首先先介绍一下VS默认提供的App.Xaml的结构,如下图 ...
- 前端面试题整理——手写bind函数
var arr = [1,2,3,4,5] console.log(arr.slice(1,4)) console.log(arr) Function.prototype.bind1 = functi ...
- python 精华梳理(已理解并手写)--全是干货--已结
基础部分 map,reduce,filter,sort,推导式,匿名函数lambda , 协程,异步io,上下文管理 自定义字符串转数字方法一不使用reduce import re def str2i ...
- 手写bind函数
实现bind函数 参考MDN提供的Polyfill方案 Function.prototype.myBind = function(context){ //这里对调用者做一个判断,如果不是函数类型,直接 ...
- C++之手写strlen函数
代码: int strlen(const char *str){ assert(str!=NULL); intlen=; while((*str++)!='\0') len++; return len ...
- js面试题之手写节流函数和防抖函数
函数节流:不断触发一个函数后,执行第一次,只有大于设定的执行周期后才会执行第二次 /* 节流函数:fn:要被节流的函数,delay:规定的时间 */ function throttle(fn,dela ...
- 常见的JS手写函数汇总(代码注释、持续更新)
最近在复习面试中常见的JS手写函数,顺便进行代码注释和总结,方便自己回顾也加深记,内容也会陆陆续续进行补充和改善. 一.手写深拷贝 <script> const obj1 = { name ...
随机推荐
- DOM Document.readyState 属性
感谢原文作者:MDN 原文地址:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/readyState 描述 一个document 的 ...
- 通过bindservice方式调用服务方法里面的过程
为什么要引入bindService:目的为了调用服务里面的方法 (1)定义一个服务 服务里面有一个方法需要Activity调用 (2)定义一个中间人对象(IBinder) 继承Binder (3)在o ...
- iOS 获取通讯录中联系人的所有属性 by - zfqj
1 ABAddressBookRef addressBook = ABAddressBookCreate(); 2 3 CFArrayRef results = ABAddressBookCopyAr ...
- iOS中处理时间的类
登录|注册 sakulafly的专栏 目录视图 摘要视图 订阅 Markdown博文大赛清新开启 天天爱答题 一大波C币袭来 中国云计算大会演讲议题公布 大 ...
- Nginx+Tomcat 实现负载均衡 ,动静分离集群部署
Nginx + Tomcat 实现负载均衡,动静分离集群部署 1.Nginx实现负载均衡原理 2.Nginx配置反向代理主要参数 3.实验 1.Nginx实现负载均衡原理: Nginx服务器作为前端, ...
- Docker的数据管理、网络通信和dockerfile
Docker的数据管理.网络通信和dockerfile 目录 Docker的数据管理.网络通信和dockerfile 一.Docker的数据管理 1. 数据卷 1.1 数据卷定义 1.2 数据卷配置 ...
- PHP面试笔试宝典
PHP面试笔试宝典 来自<PHP程序员面试笔试宝典>,涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书. PHP题目 一.单例模式是在应用程序中最多 ...
- 《PHP程序员面试笔试宝典》——如何进行自我介绍?
本文摘自<PHP程序员面试笔试宝典> PHP面试技巧分享,PHP面试题,PHP宝典尽在"琉忆编程库". 自我介绍是面试中至关重要的一个步骤,很多面试官对求职者提出的第一 ...
- mysqlCRUD
一.介绍 CRUD即增加(Create).查询(Retrieve).更新(Update).删除(Delete)四个单词的首字母缩写. In computing, CRUD is an acronym ...
- linux可以这样玩 之 杂乱无章的随笔(不定期更新)
文章目录 快速重命名 vim的进化 vim高亮当前行 vim列编辑 vim块编辑 vim行编辑 vim 中替换内容 vim保留当前已经编辑的内容,切换到其他用户继续编辑 修改服务的进程限制 CentO ...