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

手撕JS实现call,apply,bind

  • call和apply实现思路主要是:
    • 判断是否是函数调用,若非函数调用抛异常
    • 通过新对象(context)来调用函数
      • 给context创建一个fn设置为需要调用的函数
      • 结束调用完之后删除fn

call:

    Function.prototype.myCall = function (context) {// 先判断调用myCall是不是一个函数// 这里的this就是调用myCall的if (typeof this !== 'function') {throw new TypeError("Not a Function")}// 不传参数默认为windowcontext = context || window// 保存thiscontext.fn = this// 保存参数let args = Array.from(arguments).slice(1)   //Array.from 把伪数组对象转为数组// 调用函数let result = context.fn(...args)delete context.fnreturn result}function sayHi() {console.log(`Hi, I'm ${this.name}`);}const person = { name: "Alice" };sayHi.myCall(person); // 输出 "Hi, I'm Alice"

就相当于是把myCall的调用者,也就是sayHi那个函数,重新赋值给传给myCall的context参数上下文,也就是person上下文对象,就相当于person对象有了这个方法,然后通过person调用这个方法,this自然就指向了perosn,也就是myCall的参数这样就改变了sayHi函数调用是它内部的this的指向,因为通过myCall函数真正调用sayHi的是person

apply:

Function.prototype.myApply = function (context) {// 判断this是不是函数if (typeof this !== "function") {throw new TypeError("Not a Function")}let result// 默认是windowcontext = context || window// 保存thiscontext.fn = this// 是否传参if (arguments[1]) {result = context.fn(...arguments[1])} else {result = context.fn()}delete context.fnreturn result}

apply和call唯一的不同就是,apply的第二个参数是一个数组或者类数组,故在函数内部需要判断是否传递了第二个参数,如果有,就需要将数组解构,再传给函数

bind:


    Function.prototype.myBind = function(context){
// 判断是否是一个函数
if(typeof this !== "function") {
throw new TypeError("Not a Function")
}
// 保存调用bind的函数
const _this = this 
// 保存参数
const args = Array.prototype.slice.call(arguments,1)
// 返回一个函数
return function F () {
// 判断是不是new出来的
if(this instanceof F) {
// 如果是new出来的
// 返回一个空对象,且使创建出来的实例的__proto__指向_this的prototype,且完成函数柯里化
return new _this(...args,...arguments)
}else{
// 如果不是new出来的改变this指向,且完成函数柯里化
return _this.apply(context,args.concat(...arguments))
}

}

 

http://www.dtcms.com/a/427496.html

相关文章:

  • 【Java学习】类加载与实例化过程
  • [xboard] 19 kernel Makefile逐行分析1
  • 《足垒球百科》什么是足球、垒球、足垒球·垒球1号位
  • Process Monitor 学习笔记(5.1):Procmon 概述、抓取原理与常见用途
  • 重塑自然之美:朱小颜健康科技有限公司,开启非侵入式面部美学新时代
  • 站长工具关键词排名怎么查淘宝刷单网站制作
  • 做一个网站的详细教学建设通是正规网站吗
  • Redis Set 类型全解析
  • OpenSSH6 双库链接问题排查与解决总结
  • PyTorch实战车牌识别 小张的停车场项目逆袭之旅
  • IDEA 2025.2正式发布,AI能力有重大更新
  • 【Nginx开荒攻略】静态文件服务深度解析:MIME类型映射与优化实战
  • 郑州社交网站开发网推项目
  • 专做品牌网站手机微网站 模板
  • MQTT Dashboard 访问控制
  • 微算法科技(NASDAQ MLGO)研究基于信任场模型的异构物联网区块链分片算法,提高区块链的可扩展性
  • 数据结构13003考前急救
  • 教育门户网站建站工商登记查询网官网
  • 线代一轮复习
  • Qt解决不同线程,调用对方的函数
  • 开发避坑指南(60):Mysql导入数据报错ERROR 2006 (HY000) MySQL server has gone away解决方案
  • 手机网络不好怎么回事但信号是满的南宁百度seo优化
  • 网站建设怎样设置动态背景风景网站的制作
  • Java-138 深入浅出 MySQL Spring Boot 事务传播机制全解析:从 REQUIRED 到 NESTED 的实战详解 传播机制原理
  • Hadoop实战:从海量数据到AI决策的落地方法论
  • springboot+vue个人财务小程序(源码+文档+调试+基础修改+答疑)
  • 季休节能型遥测终端机RTU-为农业灌溉场景量身定制!
  • 【轨物方案】变频器物联网软硬件一站式解决方案
  • 如何选择合适的EDI软件?
  • 解决【npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。】问题