自己实现call|bind|apply三兄dei

要简单实现call、bind、apply首先要弄清楚这哥仨是啥,调用入参返回值都是什么,然后照葫芦画瓢,一点点填起来就好了;
能看思考咋实现的想必已经不需要在多赘言三个方法了,直接开始搞起;

首先这哥仨都是改变this指向,简化问题就是实现myX把fn.myX(arg)中的参数传递给fn,并把fn的this修改成arg;

	var name = 'dahuang';
    function a( ){
        console.log(this.name);
    }
    obj = {name:'mimi'}
    a();
    a.call(obj)
    a.apply(obj)
    a.bind(obj)
    /*	log
		dahuang
		mimi
		mimi
	*/

call和apply在改变this的基础上,并且把调用的函数立即执行了;bind还需要另外调用一下,所以先处理call和apply

最简单的实现

	Function.prototype.myX = function (arg){
        arg.fn = this;
        arg.fn();
    }
    a.myX(obj);
    //等同于
    let obj = {
		name:'mimi',
		fn:function(){console.log(this.name)}
	}
	obj.fn();

这里是通过给obj绑定方法fn,值为a,并且直接调用,进而改变了方法a的this;
众所周知,call和apply入参是有区别的,指着这一个最简单实现肯定不靠谱,所以接下来按照区别,分别实现myCall和myApply;

call

call接受若干个参数,返回调用函数的返回值,如果没有返回值就是undefined;

	Function.prototype.myCall = function (arg){
        arg.fn = this;
        let rest = [...arguments].slice(1);//第一个是this把他删了剩下的就是参数
        let result = arg.fn(...rest);//解构依次传入参数
        delete arg.fn;//用完记得删掉,要不污染obj
        return result;//有啥反回啥
    }

apply

apply和call的区别就是接受参数是一个数组,其他度一样,直接吧mycall拿过来

	Function.prototype.myCall = function (arg){
        arg.fn = this;
        let rest = arguments[1];//只需要第二个参数
        let result = arg.fn(...rest);//解构依次传入参数
        delete arg.fn;//用完记得删掉,要不污染obj
        return result;//有啥反回啥
    }

基本就完事了,但想起有可能不穿参数,这么写就会报error再加个兼容

	Function.prototype.myApply = function (arg){
        arg.fn = this;
        let result;
        if(arguments[1]){
            result = arg.fn(...arguments[1]);
        }else{
            result = arg.fn();
        }
        delete arg.fn;//用完记得删掉,要不污染obj
        return result;//有啥反回啥
    }

bind

最后是bind,bind稍微麻烦一点点,首先bind返回的是一个新的函数,并且入参除了第一个是this,后边参数传啥都行;

	Function.prototype.myBind = function (arg){
        arg.fn = this;  
        console.log(arg)
        let rest = [...arguments].slice(1);
        let that = this;
        return function(){
            return arg.fn(...rest)
        }
    }

简单的几个实现可能不是很严谨,有些东西没有考虑到,但是基本满足了三兄dei的使用;写完之后发现并没有多难,静下心来慢慢屡就是了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值