自定义javascript中call、bind、apply方法
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方法的更多相关文章
- 关于javascript中call()和apply()方法的总结
前段时间在使用javascript的过程中遇到了继承的问题,自己顺便就对call()和apply()方法进行了了解. 两个方法的共同之处:这两个方法作用相同,都用来改变当前函数调用的对象,即改变thi ...
- JavaScript中call和apply方法的使用
acvaScript中的call()方法和apply()方法,在某些时候这两个方法还确实是十分重要的.1. 每个函数都包含两个非继承而来的方法:call()方法和apply()方法.2. 相同点:这两 ...
- javascript中call和apply方法
我们可以将call和apply看做是某个对象的方法,通过调用方法的形式来间接调用函数.call和apply的第一个实参是要调用函数的母对象,它是调用上下文,在函数体内通过this来获得对它的引用. 例 ...
- JavaScript中的bind,call和apply函数的用法和区别
一直没怎么使用过JavaScript中的bind,call和apply, 今天看到一篇比较好的文章,觉得讲的比较透彻,所以记录和总结如下 首先要理解的第一个概念,JavaScript中函数调用的方式, ...
- JavaScript中事件绑定的方法总结
最近收集了一些关于JavaScript绑定事件的方法,汇总了一下,不全面,但是,希望便于以后自己查看. JavaScript中绑定事件的方法主要有三种: 1 在DOM元素中直接绑定 2 JavaScr ...
- Javascript中call和apply
在上一章http://www.cnblogs.com/meiyh/p/6207671.html 我有提到javascript很重要的this关键字,现在我们结合这个关键字使用的下面的两个关键字: ca ...
- JavaScript中this的使用方法总结
JavaScript中this的使用方法总结 在JavaScript中,this的使用分为四种场景,具体请参考阮一峰老师关于this的讲解 第一种情况是纯函数使用 var x =1 ; functio ...
- 说说 JavaScript中 call和apply
下面有关JavaScript中 call和apply的描述,错误的是? call与apply都属于Function.prototype的一个方法,所以每个function实例都有call.apply属 ...
- Jquery中$(document).ready()与传统JavaScript中的window.onload方法的区别(2016/8/3)
Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间 ...
- Javascript中alert</script>的方法
Javascript中alert</script>的方法: <%@ page language="java" import="java.util.*&q ...
随机推荐
- Prism Sample 7 Modules Code
例7对注册Module使用了配置命令. 见app.xaml.cs: 1 using Modules.Views; 2 using Prism.Ioc; 3 using Prism.Modularity ...
- Wolai 使用教程:嵌入小组件库,打造精美、强大的知识库主页
Wolai /我来云笔记在 2022.7.11 日的更新中,支持嵌入包括 NotionPet.芦笋.Replit 等在内的第三方应用.感谢 Wolai 云笔记官方对于 NotionPet 的支持. 趁 ...
- SVN添加新的用户
1.首先确定svn的文件夹的位置 find / -name svn 2.通过find找到svn地址之后,cd进入 /var/svn/ 下 cd /var/svn/ 3.修改/var/svn/下面的au ...
- 2022-12-24:给定一个字符串s,其中都是英文小写字母, 如果s中的子串含有的每种字符都是偶数个, 那么这样的子串就是达标子串,子串要求是连续串。 返回s中达标子串的最大长度。 1 <= s的长
2022-12-24:给定一个字符串s,其中都是英文小写字母, 如果s中的子串含有的每种字符都是偶数个, 那么这样的子串就是达标子串,子串要求是连续串. 返回s中达标子串的最大长度. 1 <= ...
- 2022-01-18:将数组分成两个数组并最小化数组和的差。 给你一个长度为 2 * n 的整数数组。你需要将 nums 分成 两个 长度为 n 的数组,分别求出两个数组的和,并 最小化 两个数组和之
2022-01-18:将数组分成两个数组并最小化数组和的差. 给你一个长度为 2 * n 的整数数组.你需要将 nums 分成 两个 长度为 n 的数组,分别求出两个数组的和,并 最小化 两个数组和之 ...
- 2021-09-02:IP 到 CIDR。给定起始IP和整数n,返回长度最小的CIDR块。力扣751。比如:ip=255.0.0.7,n=10,输出:[“255.0.0.7/32“,“255.0.0.
2021-09-02:IP 到 CIDR.给定起始IP和整数n,返回长度最小的CIDR块.力扣751.比如:ip=255.0.0.7,n=10,输出:["255.0.0.7/32" ...
- Nacos必知必会:这些知识点你一定要掌握!
前言 Nacos 是一个开源的服务发现.配置管理和服务治理平台,是阿里巴巴开源的一款产品. Nacos 可以帮助开发者更好地管理微服务架构中的服务注册.配置和发现等问题,提高系统的可靠性和可维护性. ...
- 5.5. Java并发工具类(如CountDownLatch、CyclicBarrier等)
5.5.1 CountDownLatch CountDownLatch是一个同步辅助类,它允许一个或多个线程等待,直到其他线程完成一组操作.CountDownLatch有一个计数器,当计数器减为0时, ...
- Linux 下 R 源码安装指南
本文章同步自作者的语雀知识库,请点击这里阅读原文. 如果你使用的 Linux 系统 GCC 版本太低, 又没有 root 权限 (即使有 root 权限又担心升级 GCC 带来的风险) ; 同时你又不 ...
- MAUI Blazor 项目实战 - 从0到1轻松构建多平台应用UI
前言 最近在项目中尝鲜了MAUI,总体感受下来还是挺不错的,优缺点并存,但是瑕不掩瑜,目前随着.Net版本的迭代升级对它的支持也越来越友好,相信未来可期!感兴趣的朋友欢迎关注.文章中如有不妥的地方,也 ...