首页 > 其他分享 >手写-call

手写-call

时间:2022-10-22 17:25:52浏览次数:45  
标签:obj name call arguments context 手写 fn

call的作用

function myFn () {
  console.log(this.name)
  console.log(arguments)
}
const obj = {
  name: 'zs'
}
myFn.call(obj,'aaa','bbb')

//call中第一个接收的参数为需要改变的this指向,后续参数为调用参数传参,call会自调用
//运行结果
zs
[Arguments] { '0': 'aa', '1': 'bb' }

实现思路

  1. 普通函数fn本质上也是一个对象,我们将mycall方法挂载到Function.prototype上
    此时调用fn,发现它没有mycall方法,之后就会向原型链上去查找
    找到了mycall方法,此时我们打印this,这个this指向的是fn,也就是谁调用它就指向谁
    此时我们需要更改它的指向
    将需要指向的obj传递进来

  2. 此时在obj下挂载一个函数,fn2
    也就是obj.fn2指向当前的fn函数
    就可以通过我们之前的this,
    obj.fn2=this
    此时
    也就是相当于

obj={
  name:'zs'
  fn2:function(){
    return fn(){console.log(this.name)}
  }
}

我们在调用fn中的this.name,就会向它的上层中去寻找name,也就是达到了改变this指向的问题

  1. 下一步是考虑接受参数
    将arguments进行slice切割,之后传递到fn中即可。这里可以回顾一下将arguments为数组转换为数组的几个常用方法
    1. 使用扩展运算符 [...arguments]
    2. Array.from()
    3. Array.prototype.slice.apply(arguments)
    4. 使用for循环遍历,最后返回新数组

代码实现

Function.prototype.mycall = function (context) {
  // 短路运算符,如果有context,则就是context,否则就等于window
  let args = [...arguments].slice(1)
  context = context || window
  context.fn = this
  context.fn(...args)
  delete context.fn
}
myFn.mycall(obj, 'aaa', 'bbb')

标签:obj,name,call,arguments,context,手写,fn
From: https://www.cnblogs.com/zx529/p/16816692.html

相关文章

  • Jupyter笔记[1]-MNIST手写数字识别
    jupyter集成了常用python框架docker的jupyter/tensorflow-notebook镜像包含了tensorflow,scipy等主流框架我们还可以在Jupyter内打开终端,用pip或其他工具安装软件包除了......
  • MindSpore手写数字识别体验
    今天带大家体验一下MindSpore这个AI框架来完成手写数字识别的任务1.环境准备使用Anaconda创建虚拟环境:condacreate-nmindsporepython=3.8创建完成后会显示......
  • 驱动开发:内核枚举进程与线程ObCall回调
    在笔者上一篇文章《驱动开发:内核枚举Registry注册表回调》中我们通过特征码定位实现了对注册表回调的枚举,本篇文章LyShark将教大家如何枚举系统中的ProcessObCall进程回调......
  • 驱动开发:内核枚举进程与线程ObCall回调
    在笔者上一篇文章《驱动开发:内核枚举Registry注册表回调》中我们通过特征码定位实现了对注册表回调的枚举,本篇文章LyShark将教大家如何枚举系统中的ProcessObCall进程回调以......
  • 手写基于Java RMI的RPC框架
    留给读者其中最大的区别就是ZooKeeper注册中心,注册中心可以有读写监听器,这是一个优势,可以用来实现订阅通知,也能做数据的同步,甚至可以做基于读写分离的RPC框架,而且它是基......
  • Callable接口
    Callable接口特点1.有返回2.可以抛出异常代码实现,Callable接口开启线程publicclassCallableTest{publicstaticvoidmain(String[]args)throwsExecution......
  • 直播软件开发,手写导航栏切换页面
    直播软件开发,手写导航栏切换页面 <style>  .container{    width:100%;    letter-spacing:1px;  }  .navBox{    width:1200......
  • 手写flat 与 flatMap
    今天又收获一个生产故障,原因是测试过程中在浏览器里测的,浏览器版本较高,然后这个项目是内嵌在客户端里面,客户端内的浏览器版本稍微低一点,不支持flat方法和flatMap方法,所以。......
  • 手写自定义springboot-starter,感受框架的魅力和原理
    一、前言Springboot的自动配置原理,面试中经常问到,一直看也记不住,不如手写一个starter,加深一下记忆。看了之后发现大部分的starter都是这个原理,实践才会记忆深刻。核心思......
  • 手动实现call、apply、bind
    call,apply,bind作为改变this指向的法宝,那么它们是怎么做到的呢,接下来尝试边分析、边构造:我们先来构造一个mycall骨架,把功能添加到原型链让函数依附于某个对象,并且以对象......