理解并手写 call() 函数
手写自己的call,我们要先通过call的使用,了解都需要完成些什么功能?
call()进行了调用,是个方法,已知是建立在原型上的,使用了多个参数(绑定的对象+传递的参数)。
我们把手写的函数起名为myCall,obj作为形参承载传过来的第一个参数(即绑定的对象)。
Function.prototype.myCall = function(obj){}
call的调用对this的指向进行了改变,而this是函数,这是前提(对this进行判断)。
Funtion.prototype.myCall = function(obj){
// 判断调用对象是否为函数
if(typeof this !== 'function'){
console.error('type error')
}
}
同理应当判断是否传入了参数,如果没有传入参数,则绑定的对象设置为window。
Funtion.prototype.myCall = function(obj){
if(typeof this !== 'function'){
console.error('type error')
}
// 判断绑定的对象
obj = obj || window;
}
要调用这个this方法,我们可以先将其作为对象的属性方法,然后调用。
Function.prototype.myCall = function(obj){
if(typeof this !== 'function'){
console.error('type error!');
}
obj = obj || window;
// 添加属性方法,并调用
obj.fn = this;
obj.fn();
}
call调用完后,拥有使用完方法后的返回值,所以肯定要将方法的执行结果保存并返回。
Function.prototype.mycall = function(obj){
if(typeof this !== 'function'){
console.error('type error!')
}
obj = obj || window;
obj.fn = this;
// 将执行结果保存,并返回
let result = obj.fn();
return result;
}
在原对象中,并没有obj.fn属性,所以我们要将其进行删除。
Function.prototype.mycall = 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;
}
最后考虑下方法中使用的参数(从传递过来的第二个参数开始),通过slice()进行切割,并拼凑为数组。
Function.prototype.mycall = function(obj){
if(typeof this !== 'function'){
console.error('type error!')
}
// 获取正确参数
let args = [...arguments].slice(1)
obj = obj || window;
obj.fn = this;
let result = obj.fn(...args);
delete obj.fn;
return result;
}
最后通过一个例子,来验证是否达到call()的功能要求。
Function.prototype.myCall = function(obj) {
if (typeof this !== 'function') {
console.error('type error!');
}
obj = obj || window;
let args = [...arguments].slice(1);
obj.fn = this;
let result = obj.fn(...args)
delete obj.fn;
return result;
}
let dog = {
name: '狗',
eat(food1, food2) {
console.log(this.name + '爱吃' + food1 + food2);
}
}
let cat = {
name: '猫',
}
dog.eat.call(cat, '鱼', '肉'); // 猫爱吃鱼肉
dog.eat.myCall(cat, '鱼', '肉'); // 猫爱吃鱼肉
另外两篇:'对apply()函数的分析' 和 '对bind()函数的分析' 。
理解并手写 call() 函数的更多相关文章
- 理解并手写 bind() 函数
有了对call().apply()的前提分析,相信bind()我们也可以手到擒来. 参考前两篇:'对call()函数的分析' 和 '对apply()函数的分析',我们可以先得到以下代码: Functi ...
- 理解并手写 apply() 函数
apply()函数,在功能上类似于call(),只是传递参数的格式有所不同. dog.eat.call(cat, '鱼', '肉'); dog.eat.apply(cat, ['鱼', '肉']); ...
- WPF启动流程-自己手写Main函数
WPF一般默认提供一个MainWindow窗体,并在App.Xaml中使用StartupUri标记启动该窗体.以下通过手写实现WPF的启动. 首先先介绍一下VS默认提供的App.Xaml的结构,如下图 ...
- python 精华梳理(已理解并手写)--全是干货--已结
基础部分 map,reduce,filter,sort,推导式,匿名函数lambda , 协程,异步io,上下文管理 自定义字符串转数字方法一不使用reduce import re def str2i ...
- 前端面试题整理——手写bind函数
var arr = [1,2,3,4,5] console.log(arr.slice(1,4)) console.log(arr) Function.prototype.bind1 = functi ...
- 手写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 ...
- 【OpenCV学习笔记】之六 手写图像旋转函数---万丈高楼平地起
话说,平凡之处显真格,这一点也没错! 比如,对旋转图像进行双线性插值,很简单吧? 可,对我,折腾了大半天,也没有达到预期效果! 尤其是三个误区让我抓瞎好久: 1,坐标旋转公式. 这东西,要用 ...
随机推荐
- Swift字符串的介绍
字符串的介绍 字符串在任何的开发中使用都是非常频繁的 OC和Swift中字符串的区别 在OC中字符串类型时NSString,在Swift中字符串类型是String OC中字符串@"" ...
- Mysql Json函数总览 (一)
JSON函数相关文章均来自官网,此处仅做记录,以便以后查询方便. https://dev.mysql.com/doc/refman/5.7/en/json-functions.html JSON函数参 ...
- svn中.a文件无法上传解决方法
项目导入后总是缺少.a文件,如shareSDK.a,libPushSDK.a,libbaidumapapi.a等 解决方法 方法一.修改SVN配置文件 通过终端直接打开配置文件: open ~/.s ...
- 让我一时不知所措 Linux 常用命令 爱情三部曲 下部
Linux目录与文件管理 我试着把你忘记,可总在夜里想你~ 1.linux目录结构 2.查看及检索文件 3.压缩及解压缩文件 4.vi文本编辑器 1.Linux目录结构:树形目录结构根目录:所有分区, ...
- .netcore基础知识(一)
先来说说web服务器 先来一张图 一个典型的进程外托管模型 我们先看kestrel这一部分 我们在它前面放了一个方向代理服务器nginx 对http请求做预处理 kestrel本身是可以直接用作we ...
- 基于Hexo的博客管理恢复
若重装电脑或更换电脑后 该如何恢复博客的管理? 1.确保之前博客源代码文件夹及文件保存在公库或私库中 例如: 我这里采用的是闭源存放方案,故为私库 这是源码文件样式 2.在新电脑上重新安装git,no ...
- 申请免费的ssl通配符证书
吐曹: 为了给我网站配置免费的htpps证书费死劲了, 折腾了一天, 找阿里阿里给我反馈的和我自己看的一样, 没什么用 我用Certbot生成证书以后怎么访问都是阿里的免费的hppts证书, 我都把阿 ...
- PHP+mysql常考题
PHP+mysql常考题 来自<PHP程序员面试笔试宝典>,涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书. 常考的mysql基础题 问题:设教务 ...
- Solution -「CF 1342E」Placing Rooks
\(\mathcal{Description}\) Link. 在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...
- CentOS7 下 ldap 部署
环境准备 # 关闭防火墙以及selinux,生产环境中,以实际需求为准 [root@localhost ~]# hostnamectl --static set-hostname ldap-serve ...