前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >手动实现apply、call、bind

手动实现apply、call、bind

作者头像
WindRunnerMax
发布于 2020-08-27 02:33:39
发布于 2020-08-27 02:33:39
59100
代码可运行
举报
文章被收录于专栏:Czy‘s BlogCzy‘s Blog
运行总次数:0
代码可运行

手动实现apply、call、bind

每个Function对象都存在apply()call()bind()方法,其作用都是可以在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。

apply

funct.apply(thisArg, [argsArray]) thisArg: 必选,在funct函数运行时使用的this值,this可能不是该方法看到的实际值,如果这个函数处于非严格模式下,则指定为nullundefined时会自动替换为指向全局对象,原始值会被包装。 argsArray: 可选,传递一个参数数组或者类数组对象,其中的数组元素将作为单独的参数传给funct函数,如果该参数的值为nullundefined,则表示不需要传入任何参数。 实现思路,类似于Function.prototype.apply(),同样将_apply()方法挂载到Function.prototype,使得函数对象能够直接调用,在调用funct._apply()时,在_apply()方法中的this指向的是funct对象,将此funct对象作为一个变量赋予将要绑定的对象的一个属性中,使用将要绑定的对象来调用这个funct,即可实现this指针指向将要绑定的对象,对于参数的处理,直接使用ES6Spread运算符将数组展开作为参数传递。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
window.a = 1; // 定义一个全局变量
var obj = {a: 2} // 定义一个对象用来绑定
var funct = function(b, c) { console.log(this.a,b,c); return 1; }; // 定义一个函数用来执行

funct(1, 2); // 1 1 2  // 直接执行,相当于window.funct(1, 2),this绑定于window
funct.apply(obj, [1, 2]); // 2 1 2 // 使用apply将this绑定到obj对象

Function.prototype._apply = function(base, args) { // 拓展Function原型
    base = base || window; // 传递绑定的对象为null或undefined时指向window
    base.fn = this; // 调用_apply时的this指向的是调用者也就是函数对象,将函数对象赋值给base对象的一个属性
    var result = base.fn(...args); // 调用base.fn时,fn中的this指针指向的是base,并使用Spread操作符展开参数传参
    delete base.fn; // 删除base对象的fn属性
    return result; // 将返回值返回
}

funct._apply(obj, [1, 2]); // 2 1 2 // this绑定到了obj对象

call

funct.call(thisArg[, arg1[, arg2[, ...]]]) thisArg: 必选,在funct函数运行时使用的this值,this可能不是该方法看到的实际值,如果这个函数处于非严格模式下,则指定为nullundefined时会自动替换为指向全局对象,原始值会被包装。 arg1, arg2, ...: 可选,指定的参数列表。 实现思路,类似于Function.prototype.call(),同样将_call()方法挂载到Function.prototype,使得函数对象能够直接调用,在调用funct._call()时,在_call()方法中的this指向的是funct对象,将此funct对象作为一个变量赋予将要绑定的对象的一个属性中,使用将要绑定的对象来调用这个funct,即可实现this指针指向将要绑定的对象,对于参数的处理,使用ES6Rest操作符来接收剩余参数,使用ES6Spread运算符将数组展开作为参数传递。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
window.a = 1; // 定义一个全局变量
var obj = {a: 2} // 定义一个对象用来绑定
var funct = function(b, c) { console.log(this.a,b,c); return 1; }; // 定义一个函数用来执行

funct(1, 2); // 1 1 2  // 直接执行,相当于window.funct(1, 2),this绑定于window
funct.call(obj, 1, 2); // 2 1 2 // 使用call将this绑定到obj对象

Function.prototype._call = function(base, ...args) { // 拓展Function原型,使用Rest操作符接收剩余参数
    base = base || window; // 传递绑定的对象为null或undefined时指向window
    base.fn = this; // 调用_call时的this指向的是调用者也就是函数对象,将函数对象赋值给base对象的一个属性
    var result = base.fn(...args); // 调用base.fn时,fn中的this指针指向的是base,并使用Spread操作符展开参数传参
    delete base.fn; // 删除base对象的fn属性
    return result; // 将返回值返回
}

funct._call(obj, 1, 2); // 2 1 2 // this绑定到了obj对象

bind

funct.bind(thisArg[, arg1[, arg2[, ...]]]) thisArg: 必选,调用绑定函数时作为this参数传递给目标函数的值,如果使用new运算符构造绑定函数,则忽略该值,当作为回调提供时,作为thisArg传递的任何原始值都将转换为object,如果bind函数的参数列表为空,或者thisArgnullundefined,执行作用域的this将被视为新函数的thisArgarg1, arg2, ...: 可选,当目标函数被调用时,被预置入绑定函数的参数列表中的参数。 实现思路,类似于Function.prototype.bind(),同样将_bind()方法挂载到Function.prototype,使得函数对象能够直接调用,利用箭头函数在词法上绑定this值的特性,返回一个指定了this的函数,倘若不使用箭头函数,也可以将this值分配给封闭的变量来构建闭包,然后是类似于apply方法的实现,来绑定this到指定的对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
window.a = 1; // 定义一个全局变量
var obj = {a: 2} // 定义一个对象用来绑定
var funct = function(b, c) { console.log(this.a,b,c); return 1; }; // 定义一个函数用来执行

funct(1, 2); // 1 1 2  // 直接执行,相当于window.funct(1, 2),this绑定于window
var bindFunct = funct.bind(obj, 1, 2); // 使用bind将this绑定到obj对象,bind方法返回一个原函数的拷贝,并拥有指定的this值和初始参数。
bindFunct(); // 2 1 2 

Function.prototype._bind = function(base, ...args1) { // 拓展Function原型,使用Rest操作符接收剩余参数
    return (...args2) => { // 箭头函数不会生成自身作用域下的this,会从自己的作用域链的上一层继承this
        base = base || window; // 传递绑定的对象为null或undefined时指向window
        base.fn = this; // 调用箭头函数时的this指向的是调用者也就是函数对象,将函数对象赋值给base对象的一个属性
        var result = base.fn(...args1, ...args2); // 调用base.fn时,fn中的this指针指向的是base,并使用Spread操作符展开参数传参
        delete base.fn; // 删除base对象的fn属性
        return result; // 将返回值返回
    }
}

var _bindFunct = funct._bind(obj, 1, 2); // 绑定对象
_bindFunct(); // 2 1 2 

每日一题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://github.com/WindrunnerMax/EveryDay

参考

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://www.jianshu.com/p/57a876fe66c8
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-05-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JS 手写: call、apply、bind
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
Cellinlab
2023/05/17
1.6K0
一文理解 this、call、apply、bind
记得差不多在两年多之前写过一篇文章 两句话理解js中的this,当时总结的两句话原话是这样的:
木子星兮
2020/03/17
4040
JavaScript 设计模式学习第二篇-关于this、new、bind、call、apply
虽然标题关于this、new、bind、call、apply,但实际上这些都离不开 this,因此本文将着重讨论 this,在此过程中分别讲解其他知识点。
越陌度阡
2020/11/26
2960
一文理解 this、call、apply、bind
记得差不多在两年多之前写过一篇文章 两句话理解js中的this[1],当时总结的两句话原话是这样的:
木子星兮
2020/07/17
3850
call、apply、bind
刚开始写技术笔记的时候,很浅显的写了一篇this的指向问题,现在看起来不能说错误百出,但也确实是没什么技术水平。今天分享自己对于call、apply、bind新的认识,并手写一个自己的call、apply、bind。
wade
2020/04/23
9870
一文搞定this、apply、call、bind
JavaScript中最容易被误解的一个方面是this关键字。看我本篇文章,它们将不会是问题。
用户8921923
2022/10/24
2070
call,apply,bind 的完全实现和理 解
apply(),call()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是第一个参数。
ZEHAN
2020/09/23
7820
JavaScript进阶教程(4)-函数内this指向解惑call(),apply(),bind()的区别
函数声明如果放在if-else的语句中,在IE8的浏览器中会出现问题,所以为了更好的兼容性我们以后最好用函数表达式,不用函数声明的方式。
AlbertYang
2020/09/08
6330
JavaScript进阶教程(4)-函数内this指向解惑call(),apply(),bind()的区别
this,call,apply,bind(万字长文)
前言 大家好啊,我是吒儿?,每天努力一点点?,就能升职加薪?当上总经理出任CEO迎娶白富美走上人生巅峰?,想想还有点小激动呢?。 这是我的第13期文章内容✍,希望能够把每一处知识点,说明白,(当然,如
达达前端
2020/06/16
1.2K0
【THE LAST TIME】this:call、apply、bind
讲道理,这篇文章有些拿捏不好尺度。准确的说,这篇文章讲解的内容基本算是基础的基础了,但是往往这种基础类的文章很难在啰嗦和详细中把持好。文中道不到的地方还望各位评论多多补充指正。
Nealyang
2019/10/18
5450
【THE LAST TIME】this:call、apply、bind
你知道多少this,new,bind,call,apply?那我告诉你
那么什么是this,new,bind,call,apply呢?这些你都用过吗?掌握这些内容都是基础中的基础了。如果你不了解,那还不赶快去复习复习,上网查阅资料啥的!
达达前端
2019/11/14
3880
面试题之:JavaScript中this以及apply/call/bind的用法
this 的 4 种绑定规则分别是:默认绑定、隐式绑定、显式绑定、new 绑定。优先级从低到高。
用户10106350
2022/10/28
2910
面试题之:JavaScript中this以及apply/call/bind的用法
彻底弄清 this call apply bind 以及原生实现
有关 JS 中的 this、call、apply 和 bind 的概念网络上已经有很多文章讲解了 这篇文章目的是梳理一下这几个概念的知识点以及阐述如何用原生 JS 去实现这几个功能
JS菌
2019/04/10
4180
彻底弄清 this call apply bind 以及原生实现
JS 的 call apply bind 方法
js的call apply bind 方法都很常见,目的都是为了改变某个方法的执行环境(context)
书童小二
2018/09/03
1.6K0
JS 的 call  apply  bind 方法
JavaScript中call,apply,bind方法的使用及原理
在JavaScript里,call(),apply(),bind()都是Function内置的三个方法, 它们的作用都是显示的绑定this的指向,三个方法的第一个参数都是this指向的对象,也就是函数在运行时执行的上下文。
伯爵
2019/10/18
1.1K0
模拟实现 call 和 apply
首先来认识一下 call 和 apply,它们都是 Function.prototype 上的方法,也就是说,所有函数都拥有的方法。
请叫我大苏
2019/10/24
4130
js基础-关于call,apply,bind的一切
函数原型链中的 apply,call 和 bind 方法是 JavaScript 中相当重要的概念,与 this 关键字密切相关,相当一部分人对它们的理解还是比较浅显,所谓js基础扎实,绕不开这些基础常用的API,这次让我们来彻底掌握它们吧!
OBKoro1
2019/08/05
1.5K0
js基础-关于call,apply,bind的一切
谈谈JavaScript中的call、apply和bind
在JavaScript中,如果想要改变当前函数调用的上下文对象的时候,我们都会联想到call、apply和bind。比如下面? var name = 'window name'; var obj =
Jimmy_is_jimmy
2019/07/31
3670
call、apply、bind实现原理
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。即:可以改变当前函数的this指向;还会让当前函数执行。
ClyingDeng
2022/11/29
3720
彻底弄清 this call apply bind 以及原生实现[2019-3-12更新]
有关 JS 中的 this、call、apply 和 bind 的概念网络上已经有很多文章讲解了 这篇文章目的是梳理一下这几个概念的知识点以及阐述如何用原生 JS 去实现这几个功能
JS菌
2019/04/10
3860
彻底弄清 this call apply bind 以及原生实现[2019-3-12更新]
相关推荐
JS 手写: call、apply、bind
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验