摘要:本文将全面的,详细解析call方法的实现原理

本文分享自华为云社区《关于 JavaScript 中 call 方法的实现,附带详细解析!》,作者:CoderBin。

本文将全面的,详细解析call方法的实现原理,并手写出自己的call方法,相信看完本文的小伙伴都能从中有所收获。

call 方法的实现

1.函数作用

调用函数,可传入参数,改变this指向

2.总体步骤

  1. 边界判断(this,context)
  2. 将调用的函数设置为对象(传入的context)的方法(改变this指向)
  3. 调用函数,得到返回值,并返回

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. 细节解析

  1. this 指向的就是调用 binCall() 的那个函数(隐式绑定);
  2. 传入的 context 参数表示:将 this 的指向改为这个参数;
  3. 改变 this 指向其实就是在 context 上添加一个临时的方法,值为 this;
  4. 调用 context.fn() 时,就已经改变了 this 的指向,同时得使用展开运算符传入参数
  5. delete context.fn 删除那个临时方法是因为已经不需要用了

7. 核心原理

通过在传入的对象上,临时新增一个方法,这个方法的值是当前 binCall 的调用者。然后 context.fn(...argArray) 调用这个函数,通过隐式绑定的方式改变了 this 的指向,最后得到结果并返回。

点击关注,第一时间了解华为云新鲜技术~

详解JS中 call 方法的实现的更多相关文章

  1. 详解js中的闭包

    前言 在js中,闭包是一个很重要又相当不容易完全理解的要点,网上关于讲解闭包的文章非常多,但是并不是非常容易读懂,在这里以<javascript高级程序设计>里面的理论为基础.用拆分的方式 ...

  2. 详解js中的寄生组合式继承

    寄生组合式继承是js中最理想的继承方式, 最大限度的节省了内存空间. js中的寄生组合式继承要求是: 1.子对象有父对象属性的副本, 且这些不应该保存在子对象的prototype上.       2. ...

  3. 详解JS中DOM 元素的 attribute 和 property 属性

    一.'表亲戚':attribute和property 为什么称attribute和property为'表亲戚'呢?因为他们既有共同处,也有不同点. attribute 是 dom 元素在文档中作为 h ...

  4. 详解Js中文件读取机制

    前言,文件读取是提高应用体验度的必须接口,应用场景中需求很频繁. Js处理文件读取,由于处于安全方面的考虑,在2000年以前,都是以“<input type="file"&g ...

  5. 详解js中的apply与call的用法

    前言 call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向.call 和 apply二者的作用完全一样,只是接受 ...

  6. 详解JS中Number()、parseInt()和parseFloat()的区别

    三者的作用: Number(): 可以用于任何数据类型转换成数值: parseInt().parseFloat(): 专门用于把字符串转换成数值: 一.Number( ): (1)如果是Boolean ...

  7. 详解 JS 中 new 调用函数原理

    JavaScript 中经常使用构造函数创建对象(通过 new 操作符调用一个函数),那在使用 new 调用一个函数的时候到底发生了什么?先看几个例子,再解释背后发生了什么. 1)看三个例子 1.1 ...

  8. 详解js中的this指向

    this指向问题是个老生常谈的问题了,现在我给大家一个例子 var obj={ bar:'Cynthia' , foo:function(){ console.log(this.bar,"w ...

  9. 详解javascript中的this对象

    详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...

随机推荐

  1. 时间模块之datatime模块、os模块、sys模块、json模块、json模块实操

    目录 一.模块的绝对导入和相对导入 二.包的概念 三.编程思想的转变 四.软件开发目录规范 五.常见的内置模块 一.时间模块之datatime模块 1.datetime.datetime.today( ...

  2. 深入剖析(JDK)ArrayQueue源码

    深入剖析(JDK)ArrayQueue源码 前言 在本篇文章当中主要给大家介绍一个比较简单的JDK为我们提供的容器ArrayQueue,这个容器主要是用数组实现的一个单向队列,整体的结构相对其他容器来 ...

  3. VIM编辑器的宏操作

    这两天看到一个小练习,要求如下: 在GVIM下,将下面这张图的内容 改成下面这样 并且指出,要用批量操作的方式,不能一行一行的键入 其实第一反应是利用正则表达式来操作,但是让用正则表达式以外的操作方式 ...

  4. qbxt五一数学Day1

    目录 I. 基础知识 1. 带余除法(小学) 1. 定义 2. 性质 2. 最大公约数(gcd)/ 最小公倍数(lcm) 1. 定义 2. 性质 3. 高精度 II. 矩阵及其应用 1. 定义 2. ...

  5. 如何记录分析你的炼丹流程—可视化神器Wandb使用笔记【1】

    本节主要记录使用wandb记录训练曲线以及上传一些格式的数据将其展示在wandb中以便分析的方法,略过注册安装部分(可使用pip intall wandb安装,注册相关issue可上网搜索),文章着重 ...

  6. Nginx 目录结构、Nginx服务控制命令

    # Nginx目录结构 # 首先推荐一个查看目录结构的工具 tree # yum install -y tree # sudo apt-get install -y tree ubuntu # 查看n ...

  7. Java学习(一)MarkDown语法

    Java学习(一)MarkDown语法 一.标题语法 一级标题 一级标题前添加一个#号 二级标题 二级标题前添加两个#号 三级标题 三级标题前添加三个#号 ... 二.字体 1.粗体 hello wo ...

  8. 来看看这位年轻的 eBay 小伙是如何成为 Committer

    介绍一下我自己 目前就职于eBay中国,专注于微服务中间件,分布式架构等领域,同时也是狂热的开源爱好者. 如何成为一个commiter 过去几个月,我一直持续在为 Apache DolphinSche ...

  9. 关于 CDH 环境中部署 Dolphinscheduler 出现 hive-jdbc 包冲突的解决办法

    目前社区小伙伴经常反映在 cdh 环境中部署 Dolphinscheduler 出现 hive 包冲突的问题,报错日志信息如下: [WARN] 2020-04-29 09:55:30.815 org. ...

  10. LuoguP3690 【模板】Link Cut Tree (LCT)

    勉强算是结了个大坑吧或者才开始 #include <cstdio> #include <iostream> #include <cstring> #include ...