call、bind、apply都是Function原型上的方法,用于改变this的指向

自定义函数

js中的call、bind、apply是用c++代码实现的,我们这里使用js代码做一个模式,没有把所有的边界情况考虑进来,仅做一个简单的实现,三个函数在使用的时候有一些需要注意的地方,在定义的时候需要把这些情况考虑进去

  • 当传入的值是基本数据类型时,call、apply、bind方法会将它转变成引用数据类型,如传入的字符串变成了 String 类型,通过Object()可以做这一转换
  • 当没有传递需要改变的this指向时,函数的this指向window(非严格模式下)
  • 当传递的this指向为null、undefined时, 函数的this指向window(非严格模式下)

call的实现

定义call函数需要注意

  • 第一个参数接收改变后的this指向,从第二个参数开始接收函数执行所需要的参数

实现代码如下

Function.prototype.iCall = function (thisArg, ...args) {
  // 1.获取执行函数
  var fn = this   // 2.将函数绑定到传递的对象上
  thisArg = thisArg || thisArg.toString() ? Object(thisArg) : window
  thisArg.fn = fn
  var result = thisArg.fn(...args)   // 3.删除传递对象的fn函数
  delete thisArg.fn   // 4.返回结果
  return result
} function foo(...args) {
  console.log('绑定的this为:', this)
  console.log('传递的参数为:', args)
} var user = {
  name: 'alice'
} // 将foo函数this指向改为user,并传递参数1,2,3
foo.iCall(user, 1, 2, 3)

执行结果为

apply的实现

定义apply函数需注意

  • 第一个参数接收改变后的this指向,第二个参数接收函数执行所需要的参数组成的【数组】

实现代码如下

Function.prototype.iApply = function(thisArg, args){
   // 1.获取执行函数
   var fn = this
   // 2.将函数绑定到传递的对象上
   thisArg = thisArg || thisArg.toString() ? Object(thisArg) : window
   thisArg.fn = fn
   var result = thisArg.fn(...args)
 
   // 3.删除传递对象的fn函数
   delete thisArg.fn
 
   // 4.返回结果
   return result
} function foo(...args){
  console.log('绑定的this为:', this)
  console.log('传递的参数为:', args)
} var str = "hello js"
var arr = ['a', 'b', 'c'] foo.iApply(str, arr)

执行结果如下

bind的实现

定义bind函数需注意

  • 第一个参数接收改变后的this指向,第二个参数接收函数执行所需要的参数
  • bind函数不会立即调用函数,而是返回一个新的函数,新函数仍然可以继续传递参数
Function.prototype.iBind = function (thisArg, ...args) {
  // 1.获取执行函数
  var fn = this   // 2.将函数绑定到传递的对象上
  thisArg = thisArg || thisArg.toString() ? Object(thisArg) : window
  thisArg.fn = fn   return function (...params) {
// 3.获取函数执行的结果
    var result = thisArg.fn(...args, ...params)     // 4.删除传递对象的fn函数
    delete thisArg.fn     // 5.返回结果
    return result
  }
} function foo(...args) {
  console.log('绑定的this为:', this)
  console.log('传递的参数为:', args)
}
var num = 0 var fn = foo.iBind(num, 20, 40)
fn(30, 50)

执行结果如下

以上就是call、bind、apply的实现方法,代码量不多,但是需要对this的指向比较了解,关于this指向也可以看看我其他的博文~

自定义javascript中call、bind、apply方法的更多相关文章

  1. 关于javascript中call()和apply()方法的总结

    前段时间在使用javascript的过程中遇到了继承的问题,自己顺便就对call()和apply()方法进行了了解. 两个方法的共同之处:这两个方法作用相同,都用来改变当前函数调用的对象,即改变thi ...

  2. JavaScript中call和apply方法的使用

    acvaScript中的call()方法和apply()方法,在某些时候这两个方法还确实是十分重要的.1. 每个函数都包含两个非继承而来的方法:call()方法和apply()方法.2. 相同点:这两 ...

  3. javascript中call和apply方法

    我们可以将call和apply看做是某个对象的方法,通过调用方法的形式来间接调用函数.call和apply的第一个实参是要调用函数的母对象,它是调用上下文,在函数体内通过this来获得对它的引用. 例 ...

  4. JavaScript中的bind,call和apply函数的用法和区别

    一直没怎么使用过JavaScript中的bind,call和apply, 今天看到一篇比较好的文章,觉得讲的比较透彻,所以记录和总结如下 首先要理解的第一个概念,JavaScript中函数调用的方式, ...

  5. JavaScript中事件绑定的方法总结

    最近收集了一些关于JavaScript绑定事件的方法,汇总了一下,不全面,但是,希望便于以后自己查看. JavaScript中绑定事件的方法主要有三种: 1 在DOM元素中直接绑定 2 JavaScr ...

  6. Javascript中call和apply

    在上一章http://www.cnblogs.com/meiyh/p/6207671.html 我有提到javascript很重要的this关键字,现在我们结合这个关键字使用的下面的两个关键字: ca ...

  7. JavaScript中this的使用方法总结

    JavaScript中this的使用方法总结 在JavaScript中,this的使用分为四种场景,具体请参考阮一峰老师关于this的讲解 第一种情况是纯函数使用 var x =1 ; functio ...

  8. 说说 JavaScript中 call和apply

    下面有关JavaScript中 call和apply的描述,错误的是? call与apply都属于Function.prototype的一个方法,所以每个function实例都有call.apply属 ...

  9. Jquery中$(document).ready()与传统JavaScript中的window.onload方法的区别(2016/8/3)

    Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间       ...

  10. Javascript中alert</script>的方法

    Javascript中alert</script>的方法: <%@ page language="java" import="java.util.*&q ...

随机推荐

  1. C#异步有多少种实现方式?

    前言 微信群里的一个提问引发的这个问题,C#异步有多少种实现方式?首先想要知道C#异步有多少中实现方式,首先我们要知道.NET提供的执行异步操作的三种模式,然后再去了解C#异步实现的方式. .NET异 ...

  2. 2020-09-10:java里Object类有哪些方法?

    福哥答案2020-09-10: registerNatives:private+static.getClass:返回此 Object 的运行时类. hashCode:返回该对象的哈希码值.equals ...

  3. 2021-11-11:打乱数组。给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。实现 Solution class:Solutio(int[] nums) 使用整数数组 nums

    2021-11-11:打乱数组.给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组.实现 Solution class:Solutio(int[] nums) 使用整数数组 nums ...

  4. 源码解析:django的CSRF认证

    详解Django的CSRF认证 1.csrf原理 csrf要求发送post,put或delete请求的时候,是先以get方式发送请求,服务端响应时会分配一个随机字符串给客户端,客户端第二次发送post ...

  5. 谈谈ChatGPT是否可以替代人

    起初我以为我是搬砖的,最近发现其实只是一块砖,哪里需要哪里搬. 这两天临时被抽去支援跨平台相关软件开发,帮忙画几个界面.有了 ChatGPT 之后就觉得以前面向 Googel 编程会拉低我滴档次和逼格 ...

  6. tryhackme_nmap

    https://www.cnblogs.com/-Lucky-/p/17100073.html Nmap基本端口扫描 nmap中考虑的端口状态 Open:表示服务正在侦听指定端口. Closed:表示 ...

  7. The shell

    The shell shell是什么? 如今的计算机有着多种多样的交互接口让我们可以进行指令的的输入,从炫酷的图像用户界面(GUI),语音输入甚至是 AR/VR 都已经无处不在. 这些交互接口可以覆盖 ...

  8. 2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言, 其左右子结点分别位于 (row + 1, col -

    2023-06-06:给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列. 对位于 (row, col) 的每个结点而言, 其左右子结点分别位于 (row + 1, col - ...

  9. DHCP配置;DHCP Relay配置

    目录 DHCP 配置 实验拓扑 实验需求 实验步骤 1. 基于全局地址池的DHCP服务器给客户端分配IP地址 DHCP server 上配置如下 2. 在PC1上设置为DHCP自动获取方式,ipcon ...

  10. 【技术积累】JavaSciprt中的函数【一】

    什么是函数?如何声明函数? JavaScript中的函数是一段可重复使用的代码块,它可以接受输入并返回输出. 在JavaScript中,函数是一种特殊的对象,因此可以将其存储在变量中,将其作为参数传递 ...