JS 的apply call bind的实现

JavaScript中call、apply、bind详解及手写实现 首先,我们都知道JavaScript中的this指向分为软绑定及硬绑定。并且this的指向与执行上下文有关系。在全局执行上下文中,this指向 全局对象(),在对象调用其内部方法时,this指向调用的地方,这就称为。那么如何使用呢?这就需要使用JavaScript中内置的方法来实现了。 阅读详情

JS 的apply call bind的实现

思路

三个函数简介

apply(this,[arg1,arg2…]);
call(this,arg1,arg2);
call和apply相似目的都是为了将执行函数的this值改变,后面的参数是为了填入参数
bind(this,arg1,arg2,arg3);
bind的主要目的是返回一个绑定了this的新的函数,后面的参数是填充进去的参数作为默认参数。
下面给一个阮一峰老师的例子:

var d = new Date();
d.getTime() // 1481869925657
//重写一个打印时间的函数
var print = d.getTime;
print() // Uncaught TypeError: this is not a Date object.

var print = d.getTime.bind(d); //一个新的示例应该绑定原来的Date对象
print() // 1481869925657

主要思路

apply 和call 是返回执行后的结果,所以在要绑定对象的对象内绑定一个函数执行即可。参数问题使用arguments导出一个数组将剩余的参数传入。

注:arguments是一个类似数组的东西,只有索引和长度。详见MDN。在不手动的情况下可以使用Array.prototype.slice.call(arguments);但是这里是手动情况所以要一点点读取导出。

bind 的话,对于执行上面使用eval直接运算函数。返回函数的时候使用一个闭包

代码

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
</head>
<body>
<script type="text/javascript">
    Function.prototype.myCall = function (obj) {
        if (obj==null){
            obj=window;
        }
        obj._fn_ = this;
        var args = [],len = arguments.length;
        for (var i=1;i<len;i++){
            args.push(arguments[i]);
        }
        var result = eval('obj._fn_('+args+')');
        delete obj._fn_;
        return result;
    };
    Function.prototype.myApply = function(obj,arr){
        if (obj==null){
            obj=window;
        }
        obj._fn_ = this;
        var result = eval('obj._fn_('+arr+')');
        delete obj._fn_;
        return result;
    }
    Function.prototype.myBind = function(obj){
        if (obj==null){
            obj=window;
        }
        obj._fn_ = this;
        var args = [],len = arguments.length;
        for (var i=1;i<len;i++){
            args.push(arguments[i]);
        }

        var result = function(){
            var args2 = [],len = arguments.length;
            for (var i=0;i<len;i++){
                args2.push(arguments[i]);
            }
            return   eval('console.log(obj);obj._fn_('+args.concat(args2)+')');
        };
        return result;
    };
    var a = {
        l:1,
        output:function (a) {
            console.log(Array.prototype.join.call(arguments,"-"));
            return this.l;
        }
    };
    var b = {
        l:2
    };
    var c= {
        l:3
    };
    console.log(a.output.myApply(b,[1,2,3,4,5,6,7,8]));
    var mybind = a.output.myBind(b,[1,2,3,4,5,6,7,8]);
    console.log("====================================");
    mybind(9);
    console.log("============== binb bindc======================");
    console.log(a.output.myBind(b)());
    console.log(a.output.myBind(b).myBind(c)());//有一定的包裹性obj._fn_还是那个函数
</script>
</body>
</html>

问题:a.output.myBind(b).myBind(c)结果是b

这里会有一个问题,a.output.myBind(b).myBind(c)()的结果是b,最初觉得很奇怪但是想了一下主要问题在于。bind是一个包裹性的函数,第一次bind之后函数内部的this是b而在绑定一次c之后执行的是obj_fn_这里面的this是b所以执行还是b。

Arcgis使用NDVI值遥感反演叶面积指数(LAI) 经验模型反演操作不难,主要是要多看文献,了解公式。本文中的公式我也不清楚是哪个作物的NDVI和LAI的关系(别人提供的),继续看文献整理吧。后续会在下面罗列更新一下主要公式。 阅读详情

相关推荐

《矩阵论》学习笔记(四):4.2 矩阵的QR分解

《矩阵论》学习笔记(四):4.2 矩阵的QR分解 文章目录《矩阵论》学习笔记(四):4.2 矩阵的QR分解一. Givens矩阵与Givens变换1.1. 概念与理解1.2. Givens矩阵求解方法二. Householder矩阵与Householder变换2.1. 概念与理解2.2. Householder矩阵求解方法2.3. Givens变换与Householder变换的关系三. 矩阵的QR...

shine的博客 3681

我所见过的讲"javascript中apply、call、bind"最清晰最易懂的文章

首先声明这篇文章大部分内容都是转载的,转载自ChokCoco"深入浅出妙用Javascript中apply、call、bind"这篇文章。如此好文章仅仅作为一个链接放在优快云着实可惜,所以还是自己手动敲一遍,羞涩地冠以原创之名,作为自己的知识库。阮一峰的这段话说的真好啊,绝对说出了写博客人的心声。"对我来说,博客首先是一种知识管理工具,其次才是传播工具。我的技术文章,主要用来整理我还不懂的知识。我只写那些我还没有完全掌握的东西,那些我精通的东西,往往没有动力写。炫耀从来不是我的动机,好奇才是。"

aty 3310

ISO18000-6B/6C(EPC C1G2)两个射频识别(RFID)标准协议的技术特点

目前读写器基本上是采用IMPINJ的R2000芯片和E710芯片开发,因为ISO18000-6B标准的现在应用很少,E710芯片已经不再支持ISO18000-6B标准,选择上就只有采用R2000芯片开发的UR6258超高频读写器以及手持机,这个在项目应用上需要留意。尽管ISO18000-6B标准具有上述优点,但也存在一些不足之处,特别是多标签阅读性能远远满足不了现在的应用需求,近年来发展停滞,绝大部分应用已经被ISO18000-6C(EPC C1G2)取代;#RFID# #物联网# #标准协议#

RFID设备与应用介绍 2157

阮一峰的JavaScript 教程读书笔记之面向对象编程

文章目录OOP实例对象与new命令构造函数new命令this 关键字实质使用场合(1)全局变量(2)构造函数(3)对象的方法使用注意1.避免函数多层嵌套中使用this2.避免数组处理中的`this`this绑定call函数 OOP 实例对象与new命令 构造函数 JS中的面向对象是通过构造函数(constructor)和原型链(prototype)来实现的。JavaScript 语言使用构造函数(constructor)作为对象的模板。 var Vehicle = function () { this.

一名正在成长的程序员 1227

双有源桥(DAB)进阶:EPS调制策略与Matlab/Simulink仿真实践

本文深入探讨了双有源桥(DAB)的扩展移相(EPS)调制策略及其在Matlab/Simulink中的仿真实践。通过分析EPS的两种黄金调制策略——回流功率消除和电流应力优化,结合实际工程案例,展示了如何提升DAB系统的效率和性能。文章还详细介绍了Simulink模型搭建要点和关键仿真结果,为工程师提供了实用的技术参考。

weixin_33734785的博客 484

Eclipse邂逅Deepseek:本地化部署全攻略

通过前面一系列的步骤,我们成功地在 Eclipse 中完成了 Deepseek 的本地化部署,并且对部署后的功能进行了测试和优化,还解决了可能遇到的一些常见问题。这一过程不仅让我们体验到了将强大的大语言模型与高效的开发环境相结合的魅力,也为我们在软件开发过程中带来了诸多便利。本地化部署 Deepseek 到 Eclipse,使得我们在代码编写过程中能够获得智能的代码补全和精准的问答支持,大大提高了开发效率。同时,本地化部署保障了数据的安全性和隐私性,避免了数据在传输过程中可能面临的风险。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 4522

【优雅代码】深入浅出 妙用Javascript中apply、call、bind

这篇文章实在是很难下笔,因为网上相关文章不胜枚举。 巧合的是前些天看到阮老师的一篇文章的一句话: “对我来说,博客首先是一种知识管理工具,其次才是传播工具。我的技术文章,主要用来整理我还不懂的知识。我只写那些我还没有完全掌握的东西,那些我精通的东西,往往没有动力写。炫耀从来不是我的动机,好奇才是。" 对于这句话,不能赞同更多,也让我下决心好好写这篇,网上文章虽多,大多复制粘贴,且晦涩难懂,我...

weixin_34109408的博客 401

7.12真题华为OD机试真题 新系统 - 字符串压缩编码 (Java/Py/C/C++/Js/Go)

7.12真题华为OD机试真题 新系统 - 字符串压缩编码 (Java/Py/C/C++/Js/Go)

算法大师! 841

call和apply

首先申明,本文是来自阮一峰前辈的文章,还是决定自己在敲一遍,在这里我想不用放大师的链接了(想必太多的人知道了);apply和call的作用在javascript中,call和apply都是为了改变某个函数运行的上下文(context)而存在的,换句话说就是改变函数体内部的this指向。javascript的一大特点就是,函数存在【定义时上下文】和【运行时上下文】以及【上下文是可以改变的】这样的概念。

arthur的博客 541

全网详细解决Client does not support authentication protocol requested by server;consider upgrading Mysql c

全网详细解决1251 - Client does not support authentication protocol requested by server; consider upgrading Mysql client。

念兮为美 5479

【STM32系统及仿真】基于STM32+蓝牙设计的智能窗帘系统__资料编号8

本项目设计并实现了一种基于STM32单片机的智能窗帘系统,集成了光敏传感器、温湿度传感器、蓝牙模块和OLED显示屏,实现了窗帘的自动调节、环境监测和远程控制功能。系统采用STM32F103C8T6作为主控制器,通过光敏传感器检测环境光强,温湿度传感器监测室内环境,蓝牙模块实现与手机APP的通信,用户可以通过APP远程控制窗帘的开合状态。系统在检测到环境光照强度或温度超出设定范围时,可自动调节窗帘的开合,以达到节能和提高舒适度的目的。

嵌入式阿齐Archie 2万+

【ES6】阮一峰ES6学习(六) Proxy

es6中全新设计了一个叫的类型,Proxy这个词的原意是代理,用在这里表示由它来”代理“某些操作,可以译为”代理器“,Proxy就是专门为对象设置访问代理器的,无论是读还是写都要经过代理,通过proxy就能轻松监视对象的读写过程。如何使用监视对象的读写过程呢?定义一个对象,对象当中有一个属性和属性,然后通过的方式为创建一个代理对象的构造函数需要2个参数,一个是需要代理的目标对象,另一个是代理的处理对象,在这个处理对象中可以通过方法监视对象属性的访问,通过方法监视对象设置属性的过程 1. get()方法 ge

GY的博客 7128

从零玩转Vitis裸机开发:手把手教你创建、移植与实战优化

✅ Vitis裸机开发全流程✅ 中断系统配置技巧✅ 跨平台移植方法论✅ 性能优化实战经验研究FreeRTOS移植探索AMP(非对称多处理)架构学习使用Vitis Analyzer进行性能分析技术雷达:关注Xilinx最新推出的Vitis Unified IDE,其集成了更强大的调试和分析工具。立即动手实践吧!

QQ_778132974的博客 584

原生JavaScript实现call、apply和bind

如果用call进行绑定,其实相当于在egg对象里面增加一个person函数,再用egg.person()调用就好了 简单来说就是在egg这个位置开始进行调用,然后执行person函数,如果发现了this就会绑定到egg,因为egg直接执行了person,egg是真正的调用位置,因此this指向了egg 此时的this指向window,person函数进行调用,然后执行newCall函数,发现了this,因此需要进行绑定,person才是真正调用位置,所以this指向person函数 实现call .

qq_35218523的博客 8274

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

js实现Promise,call,apply,bind

1.原生js实现Promise? // 判断变量否为function const isFunction = variable => typeof variable === 'function' // 定义Promise的三种状态常量 const PENDING = 'PENDING' const FULFILLED = 'FULFILLED' const REJEC...

我的博客 830

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

原生JS实现 call apply bind

call apply bind 的 作用 都是用来改变this的指向,在平时工作过程中,除了实现对象的继承,在写一些基础类,或者公用库方法的时候会用到它们,其他时候 call 和 apply 的应用场景并不多。 在React中bind常用来绑定事件,改变this的指向 call apply bind 的 区别 call apply方法都是在调用之后立即执行的,而bind是返回原函数,需要再调用一...

qq_37278704的博客 540

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

js模拟实现call,apply,bind

Function.prototype.call() 语法 fun.call(thisArg, arg1, arg2, …) 参数 thisArg 在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于non-strict mode,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是wind...

奋斗在路上 3397

JS手写实现call、apply、bind

目录 写在前面 call手写实现 apply手写实现 bind手写实现 写在前面 今天的主题是手写实现某些常见的js函数。在JavaScript中,我们知道改变一个函数的this指向,一般来说有这样三个函数可以帮助我们做到这样的效果,分别是call、apply、bind。但是三个函数又有所区别,具体的区别我就不详述了,大家可以去call、apply、bind详细介绍看看详细的介绍。 ...

追风Programer的博客 2634

JavaScript call,apply,bind详解及实现

1.前言 call,apply,bind这三个方法都是用来改变函数的this指向,如果有对this不熟悉的朋友,可以先看看笔者的这篇博客。 call & apply call()语法: function.call(thisArg, arg1, arg2, ...) thisArg 可选的。在 function 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值

Niall_Tonshall的博客 1263

JS手写章节(1)—手写实现call、apply、bind

JS手写章节(1)—手写实现call、apply、bind

weixin_50926010的博客 3386

JavaScript中的call、apply、 bind的用法、实现以及三者之间的区别?

相信很多同学在面试中遇到这样的问题,今天我们就彻底搞懂JavaScript中的call、apply、 bind的用法、实现以及三者之间的区别,废话不多说,直接开撸!

富朝阳的博客 3044

js实现call、apply、bind方法

js实现call、apply、bind方法 一、call 函数的实现步骤: 判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。 判断传入上下文对象是否存在,如果不存在,则设置为 window 。 处理传入的参数,截取第一个参数后的所有参数。 将函数作为上下文对象的一个属性。 使用上下文对象来调用这个方法,并保存返回结果。 删除刚才新增的属性。 返回结果。 // call函数实现 Function.prototype.myCall = function(

guoqkmiss的博客 755

js中的call、apply和bind函数实现的原理

有空的时候都会看一下掘金社区,里面的文章都很棒,也学到了很多,其实我写博客主要是让自己记个笔记,俗话说好记性不如个烂笔头,有时候会忘记,所以遇到解决问题的方法我都会记载下来,都归于项目总结这一类了。慢慢我发现我写的东西还能帮助到更多的人,这更让我开心了,同时我也告诉自己要更加严谨了,可不能误人子弟。 好了,刚刚有感而发,说了那么多开场白,下面进入正题吧。 我们先看一下call函数实现的方法 Fun...

时清云的博客 1687

JS 实现call apply bind

call、apply、bind是用于重定义函数中this所指向的对象的。借这篇文章来原生实现一下call、apply、bind。 JS实现call Function.prototype.mycall=function(context){ var context=context||window; //获取对象,当没有传递参数的时候,为window context.fn=this; ...

weixin_41973410的博客 227

JS模拟实现call,apply,bind

前言 我相信对于call,applay,bind三者之前的用法与区别,小伙伴们肯定都很清楚了,毕竟这也是面试的高频试题,之前面试的时候,当面试官提到call的时候我可是心花怒放,正准备侃侃而谈的时候,面试官说请用js模拟call的用法,限时5分钟。当时就懵了,脑子里只有它的各种用法,但内部究竟如何实现的,还真没有研究过,当时就唱了一首凉凉给自己。失败不可怕,所以今天特写文一篇,纪...

DepressedPrince的博客 396

原生 JS 实现call apply bind 等API

关于 JS 中一些重要的 api 实现, 巩固你的原生 JS 功底 1. 手写 call 方法 Function.prototype.myCall = function (context, ...args) { if (typeof context === 'object' || typeof context === 'function') { context = context || window } else { context = Object.create(null) } // 为了

qq_43778110的博客 334
上一篇: JavaScript 实现堆排序
下一篇: 前端绘制地图中的地理坐标到屏幕坐标转换的简单思路--放大、缩小、移动
yatsov
博客等级 码龄16年 52粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值