当前位置: 首页 > news >正文

手写js中call、apply、bind函数

手写call

原理

将需要改变this指向的函数暂时性的设置为需要设置this指向的对象的函数。

代码

// 定义mycall方法,所有函数对象都是Function对象
Function.prototype.mycall = function (thisArg, ...args) {// 设置this,此时this指向原函数,之后将指向thisArgthisArg.f = this// 接收剩余参数并得到结果const res = thisArg.f(...args)// 移除函数delete thisArg.f// 返回结果return res
}// 测试样例
const person = {name: '南辞w'
}
function func(numA, numB) {console.log(this)console.log(numA, numB)return numA + numB
}
const res = func.mycall(person, 2, 8)
console.log('返回值为', res)

调优

对象中可能会出现函数重名冲突,可以利用Symbol()进行处理

调优后代码

Function.prototype.mycall = function (thisArg, ...args) {const key = Symbol('key')thisArg[key] = thisconst res = thisArg[key](...args)delete thisArg[key]return res
}const person = {name: '南辞w'
}
function func(numA, numB) {console.log(this)console.log(numA, numB)return numA + numB
}
const res = func.mycall(person, 2, 8)
console.log('返回值为', res)

手写apply

原理

改变this的方法同上,但接收的参数为数组形式,可以之间用 '...' 来展开接收

代码

Function.prototype.myapply = function (thisArg, args) {const key = Symbol('key')thisArg[key] = thisconst res = thisArg[key](...args)delete thisArg[key]return res
}const person = {name: '南辞w'
}function func(numA, numB, numC) {console.log(this)console.log(numA, numB, numC)return numA + numB + numC
}const res = func.myapply(person, [2, 8, 10])
console.log('返回值为', res)

手写bind

原理

改变this指向同上,但是此函数返回的是新的函数,并且可以分批次传值,前后次序不要弄混了

代码

Function.prototype.mybind = function (thisArg, ...args) {return (...reArgs) => {return this.call(thisArg, ...args, ...reArgs)}
}const person = {name: '南辞w'
}
function func(numA, numB, numC, numD) {console.log(this)console.log(numA, numB, numC, numD)return numA + numB + numC + numD
}
const bindFunc = func.mybind(person, 1, 2)
const res = bindFunc(3, 4)
console.log('返回值为', res)

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java—反射机制详解
  • [linux][证书]证书导出公钥
  • 探索MemGPT:AI界的新宠儿
  • spring boot导入多个配置文件
  • C#用SDK打开海康工业相机,callback取图Bitmap格式,并保存
  • React启动时 Error: error:0308010C:digital envelope routines::unsupported
  • 三维手势 handpose 3D RGB 手势3D建模 三维建模-手势舞 >> DataBall
  • C语言 | Leetcode C语言题解之第434题字符串中的单词数
  • 【我的 PWN 学习手札】fastbin reverse into tcache —— tcache key 绕过
  • 科大讯飞智能体Python SDK接入流程
  • 我能禁止使用某协议的ip禁止访问我的资源吗
  • provide 和 inject
  • 容器化安装Jenkins部署devops
  • 基于SpringBoot的在线点餐系统【附源码】
  • 【Unity设计模式】Unity MVC/MVP架构介绍,及MVC/MVP框架的简单应用
  • 345-反转字符串中的元音字母
  • crontab执行失败的多种原因
  • docker容器内的网络抓包
  • eclipse(luna)创建web工程
  • Linux链接文件
  • node 版本过低
  • SpingCloudBus整合RabbitMQ
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 对象管理器(defineProperty)学习笔记
  • 反思总结然后整装待发
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 京东美团研发面经
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 网页视频流m3u8/ts视频下载
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 走向全栈之MongoDB的使用
  • 06-01 点餐小程序前台界面搭建
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #数据结构 笔记三
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (1)Hilt的基本概念和使用
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)ssm航空客运订票系统 毕业设计 141612
  • (一)Neo4j下载安装以及初次使用
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)创业家杂志:UCWEB天使第一步
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • *2 echo、printf、mkdir命令的应用
  • .net core使用ef 6
  • .NET DevOps 接入指南 | 1. GitLab 安装