call、apply 及 bind 函数
首先从以下几点来考虑如何实现这几个函数
- 不传入第一个参数,那么上下文默认为 window;
- 改变了 this 指向,让新的对象可以执行该函数,并能接受参数。
实现call
- 首先 context 为可选参数,如果不传的话默认上下文为 window;
- 接下来给 context 创建一个 fn 属性,并将值设置为需要调用的函数;
- 因为 call 可以传入多个参数作为调用函数的参数,所以需要将参数剥离出来;
- 然后调用函数并将对象上的函数删除。
Function.prototype.myCall = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
const args = [...arguments].slice(1)
const result = context.fn(...args)
delete context.fn
return result
}
apply实现
- apply 的实现也类似,区别在于对参数的处理。
Function.prototype.myApply = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
let result
// 处理参数和 call 有区别
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}
bind 的实现
bind 的实现对比其他两个函数略微地复杂了一点,因为 bind 需要返回一个函数,需要判断一些边界问题,以下是 bind 的实现
- bind 返回了一个函数,对于函数来说有两种方式调用,一种是直接调用,一种是通过 new 的方式,我们先来说直接调用的方式,
- 对于直接调用来说,这里选择了 apply 的方式实现,但是对于参数需要注意以下情况: 因为 bind 可以实现类似这样的代码 f.bind(obj, 1)(2) ,所以我们需要将两边的参数拼接起来,于是就有了这样的实现 args.concat(...arguments) 。
- 最后来说通过 new 的方式,在之前的章节中我们学习过如何判断 this ,对于 new 的情况来说,不会被任何方式改变 this ,所以对于这种情况我们需要忽略传入的 this 。
Function.prototype.myBind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
const _this = this
const args = [...arguments].slice(1)
// 返回一个函数
return function F() {
// 因为返回了一个函数,我们可以 new F(),所以需要判断
if (this instanceof F) {
return new _this(...args, ...arguments)
}
return _this.apply(context, args.concat(...arguments))
}
}
call、apply 及 bind 函数的更多相关文章
- Javascript中call、apply、bind函数
javascript在函数创建的时候除了自己定义的参数外还会自动新增this和arguments两个参数 javascript中函数也是对象,call.apply.bind函数就是函数中的三个函数,这 ...
- apply,call,bind函数作用与用法
作用 可以把方法借给其它对象使用,并且改变this的指向 a.apply(b,[3,2]);//this指向由a变为b, a的方法借给b使用 实例: function add(a,b){ ...
- 实现call、apply 及 bind 函数
今日学习内容: (1)call 函数的实现步骤: 判断调用对象是否为函数,即使是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况. 判断传入上下文对象是否存在,如果不存在,则设置为 ...
- 函数的属性和方法之call、apply 及bind
一.前言 ECMAScript中的函数是对象,因此函数也有属性和方法.每个函数都包含两个属性:length和prototype.每个函数也包含两个非继承来的方法:apply()和call(),还有一些 ...
- call,apply,bind函数
一.call函数 a.call(b); 简单的理解:把a对象的方法应用到b对象上(a里如果有this,会指向b) call()的用法:用在函数上面 var Dog=function(){ this.n ...
- javascript中函数的call,apply及bind方法
call 方法调用一个对象的一个方法,以另一个对象替换当前对象.call([thisObj[,arg1[, arg2[, [,.argN]]]]])参数thisObj可选项.将被用作当前对象的对象. ...
- 前端总结·基础篇·JS(三)arguments、callee、call、apply、bind及函数封装和构造函数
前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...
- 函数 call、apply、bind的使用
[优雅代码]深入浅出 妙用Javascript中apply.call.bind (转载而来) 这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: “对 ...
- js中函数的 this、arguments 、caller,call(),apply(),bind()
在函数内部有两个特殊的对象,arguments 和 this,还有一个函数对象的属性caller. arguments对象 arguments是一个类似数组的对象,包含着传入函数的所有参数. func ...
- 改变函数中的 this 指向——神奇的call,apply和bind及其应用
在JavaScript 中,call.apply 和 bind 是 Function 对象自带的三个方法,这三个方法的主要作用是改变函数中的 this 指向,从而可以达到`接花移木`的效果.本文将对这 ...
随机推荐
- Vue3 流程图组件库 Vue Flow 简单使用
官网 Vue Flow 官网 Vue Flow GitHub 安装 npm i --save @vue-flow/core yarn add @vue-flow/core pnpm i @vue-fl ...
- Communications link failure:The last packet successfully received from the server was 0 millisecond ago
出现这种错误的大致情况如下: 1.数据库连接长时间未使用,断开连接后,再去连接出现这种情况.这种情况常见于用连接池连接数据库出现的问题 2.数据库连接的后缀参数问题 针对上述两种情况,解决方案如下 1 ...
- AX2012 快速清空整个log表数据
如果当一个log表的数据非常大的时又需要清理时,如果允许删除全部数据,在AX里,可以 将log表的TableType调整为[TempDB], 保存同步后再将TableType设置回[Regular]即 ...
- Jmeter四、jmeter脚本组成和组件搭配
一.jmeter脚本开发原则 简单:去除无关的组件,同时能复用的尽量复用. 正确:对脚本或者业务正确性进行必要的判断,不能少也不能多(200) 高效:部分组件仅仅在脚本开发模式使用,在真正生产环境下不 ...
- Spring系列之类型转换-12
目录 类型转换 转换器 SPI 使用`ConverterFactory` 使用`GenericConverter` `ConversionService` 配置一个`ConversionService ...
- 阿里云Linux服务器安装Maven实战教程
下载地址 https://maven.apache.org/download.cgi 文件上传 把下载的文件上传到阿里云服务器 /usr/local/software 的目录(使用工具) window ...
- YII oracle
以 11.2 为例 , 注意必须要与数据库版本对应下载如下两个文件instantclient-basic-linux.x64-11.2.0.4.0.zip https://download.oracl ...
- winIO介绍
WinIO程序库允许在32位的Windows应用程序中直接对I/O端口和物理内存进行存取操作.通过使用一种内核模式的设备驱动器和其它几种底层编程技巧,它绕过了Windows系统的保护机制. 因为需要加 ...
- Chrome浏览器:Your Connection is not private 您的连接不是私密连接
在图片图片所示的任何地方输入: thisisunsafe 没错就是这么6,然后就可以访问了.输错了请刷新再来(微笑) https://blog.csdn.net/filbert_917/article ...
- python读书笔记-网页制作
socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: Socket 对象(内建)方法 Python Internet 模块: