详解JS中 call 方法的实现
摘要:本文将全面的,详细解析call方法的实现原理
本文分享自华为云社区《关于 JavaScript 中 call 方法的实现,附带详细解析!》,作者:CoderBin。
本文将全面的,详细解析call方法的实现原理,并手写出自己的call方法,相信看完本文的小伙伴都能从中有所收获。
call 方法的实现
1.函数作用
调用函数,可传入参数,改变this指向
2.总体步骤
- 边界判断(this,context)
- 将调用的函数设置为对象(传入的context)的方法(改变this指向)
- 调用函数,得到返回值,并返回
3. 详细步骤
1. 边界判断
- 判断当前 this 是否为一个函数,否则返回错误消息
- 判断传入的 context 参数是否存在,存在则使用 Object() 转换为对象赋给 context,否则将 window 赋值给 context
2. 将调用的函数设置为对象(传入的context)的方法(改变this指向)
3. 调用函数,得到返回值,并返回
- 调用函数,得到结果
- 删除 context 身上的 fn 函数
- 返回结果
4. 代码实现
/**
* !实现 binCall() 方法
* @param {*} context 绑定的对象
* @param {...any} args 剩余参数
* @returns
*/
Function.prototype.binCall = function(context, ...args) {
if (typeof this !== 'function') console.error('type Error'); // 1
context = (context!==null && context!==undefined) ? Object(context) : window
context.fn = this // 2
const result = context.fn(...args) // 3
delete context.fn;
return result
}
5. 测试代码
// 测试
function sum(num1, num2) {
console.log('sum 被执行', this);
return num1 + num2
}
// 原生的 call() 方法
console.log(sum.call({name: 'bin'},1,2));
// 自定义的 binCall() 方法
console.log(sum.binCall({name: 'bin'},1,2));
经过原生的call方法和手写的binCall方法测试,我们手动实现的binCall方法也能实现原生call方法的功能
6. 细节解析
- this 指向的就是调用 binCall() 的那个函数(隐式绑定);
- 传入的 context 参数表示:将 this 的指向改为这个参数;
- 改变 this 指向其实就是在 context 上添加一个临时的方法,值为 this;
- 调用 context.fn() 时,就已经改变了 this 的指向,同时得使用展开运算符传入参数
- delete context.fn 删除那个临时方法是因为已经不需要用了
7. 核心原理
通过在传入的对象上,临时新增一个方法,这个方法的值是当前 binCall 的调用者。然后 context.fn(...argArray) 调用这个函数,通过隐式绑定的方式改变了 this 的指向,最后得到结果并返回。
详解JS中 call 方法的实现的更多相关文章
- 详解js中的闭包
前言 在js中,闭包是一个很重要又相当不容易完全理解的要点,网上关于讲解闭包的文章非常多,但是并不是非常容易读懂,在这里以<javascript高级程序设计>里面的理论为基础.用拆分的方式 ...
- 详解js中的寄生组合式继承
寄生组合式继承是js中最理想的继承方式, 最大限度的节省了内存空间. js中的寄生组合式继承要求是: 1.子对象有父对象属性的副本, 且这些不应该保存在子对象的prototype上. 2. ...
- 详解JS中DOM 元素的 attribute 和 property 属性
一.'表亲戚':attribute和property 为什么称attribute和property为'表亲戚'呢?因为他们既有共同处,也有不同点. attribute 是 dom 元素在文档中作为 h ...
- 详解Js中文件读取机制
前言,文件读取是提高应用体验度的必须接口,应用场景中需求很频繁. Js处理文件读取,由于处于安全方面的考虑,在2000年以前,都是以“<input type="file"&g ...
- 详解js中的apply与call的用法
前言 call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向.call 和 apply二者的作用完全一样,只是接受 ...
- 详解JS中Number()、parseInt()和parseFloat()的区别
三者的作用: Number(): 可以用于任何数据类型转换成数值: parseInt().parseFloat(): 专门用于把字符串转换成数值: 一.Number( ): (1)如果是Boolean ...
- 详解 JS 中 new 调用函数原理
JavaScript 中经常使用构造函数创建对象(通过 new 操作符调用一个函数),那在使用 new 调用一个函数的时候到底发生了什么?先看几个例子,再解释背后发生了什么. 1)看三个例子 1.1 ...
- 详解js中的this指向
this指向问题是个老生常谈的问题了,现在我给大家一个例子 var obj={ bar:'Cynthia' , foo:function(){ console.log(this.bar,"w ...
- 详解javascript中的this对象
详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...
随机推荐
- 20220727-Java中方法重写override
目录 代码示例 注意事项 代码示例 public class OverrideExercise { public static void main(String[] args) { Person ja ...
- 使用Typora+EasyBlogImageForTypora写博客,无图床快速上传图片
如今,使用markdown攥写博客已成为主流,而Typora作为markdown的主流工具,广受大众好评,本文讲述从Typora的安装到快速将Typora写好的博文上传到博客园 Typora下载 Ty ...
- Ubuntu14.04或16.04下普通用户的root权限获得
Ubuntu系统默认不允许使用root登录,因此初始root帐户是不能使用的,需要在普通账户下利用sudo权限修改root密码.然后以root帐户进行相关操作. 具体操作: 1.打开系统,用普通帐户登 ...
- 两天时间学习的html的知识笔记
坚持努力背 特殊字符: 空格符 < 小于号 <> 大于号 >& 和号 &¥ 人民币 ¥ 版权 ©R 注册商标 ®. 摄氏度 ° 正负号 ±X 乘号 × 除号 ...
- AI识万物:从0搭建和部署手语识别系统 ⛵
作者:韩信子@ShowMeAI 深度学习实战系列:https://www.showmeai.tech/tutorials/42 计算机视觉实战系列: https://www.showmeai.tech ...
- SpringBoot(一、快速入门)
1.SpringBoot简介 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置, ...
- CSS 选择器(一):属性选择器
属性选择器的介绍 属性选择器顾名思义就是通过标签的属性来查找标签的选择器.让我们来回忆一下标签的属性是什么?HTML5 的所有标签共同拥有的属性叫作全局属性,除此之外还有标签自己拥有的属性,就叫作私有 ...
- JavaScript基础回顾知识点记录4-正则表达式篇(介绍基本使用)
js 中 正则表达式使用 创建正则对象和test方法使用 /* 创建正则表达式的对象 语法: var 变量 = new RegExp("正则表达式","匹配模式" ...
- docker的volume和bind mount究竟有什么区别?
不知道你在使用docker的时候,有没有注意到volume mount和bind mount的使用? 进一步说,他们之间的区别到底是什么? 接下来的内容,我们就为你揭开他们的神秘面纱. 相同之处 首先 ...
- Miller Rabbin 算法—费马定理+二次探测+随机数 (讲解+例题:FZU1649 Prime number or not)
0.引入 那年,机房里来了个新教练, 口胡鼻祖lhy 第一节课,带我们体验了暴力的神奇, 第二节课,带我们体验了随机数的玄妙, -- 那节课,便是我第一次接触到Miller Rabbin算法, 直到现 ...