自己实现call,apply,bind

自己尝试一下如何实现call,apply,bind

  • 第一步我们先在Function的原型上面新建一个函数吧.叫myApply
const obj = {
    name:'joy',
};

function getName() {
    console.log(this.name);
}

Function.prototype.newApply= function () {
    console.log(this);
};

getName.newApply(); //ƒ getName(){ console.log(this.name); }

这时候打印出来,this是getName这个函数.
根据我之前写过的一篇文章 (确定this的指向)
得知,this绑定的优先级是

箭头函数 > new > 显式 > 隐式 > 默认绑定

call,apply是属于显示绑定,那肯定不能用箭头函数和new来代替了,否则优先级就改变了,那就只能用隐式绑定的方式了

  • 所以我们要用隐式绑定的方式去改变this的指向
const obj = {
    name:'joy'
};

function getName(){
    console.log(this.name);
}

Function.prototype.newApply= function (that) {
    that.myFn = this;
    const result = that.myFn();
    return result
};

getName.newApply(obj); //joy

这里已经是初步完成了改变this指向的功能了,让我们在来完善一下

  • 加上传递参数和不传this调用
const obj = {
    name:'joy'
};

function getName(a,b){
    console.log(this.name,a,b);
}

Function.prototype.newApply = function (that,arg) {
    if(typeof this !== 'function'){
        throw this+'is not a function'
    }
    that = that || window; //因为第一个参数如果不传就会绑定到window上面
    arg = arg || [];
    that.myFn = this;
    const result = that.myFn(...arg); //解构赋值把参数传进来,先把结果存起来
    delete that.myFn; //再删除,否则就有副作用了
    return result;
};

getName.newApply(obj,[1,2]); // joy
  • 这样一个apply就完成了,可能还有些地方没考虑到,但是大概功能都出来了,call也是差不多就是传参不太一样
const obj = {
    name:'joy'
};

function getName(a,b){
    console.log(this.name,a,b);
}

  Function.prototype.newCall = function (that, ...arg) {
            if (typeof this !== 'function') {
                throw this + 'is not a function'
            }
            that = that || window; //因为第一个参数如果不传就会绑定到window上面
            that.myFn = this;
            const result = that.myFn(...arg); //解构赋值把参数传进来,先把结果存起来
            delete that.myFn; //再删除,否则就有副作用了
            return result;
        };

        getName.newApply(obj, 1, 2); // joy 1 2

以上就是apply和call自己实现的方式了.

  • 接下来到一个难点bind了,bind有点不一样,call和apply是绑定直接调用,而bind是绑定不调用,返回绑定后的函数
  • 那么直接利用apply不就可以了
    const obj = {
        name:'joy'
    };

    function getName(){
        console.log(this.name);
    }

    Function.prototype.newBind = function (that) {
        const fn = this;
        return function () {
            fn.apply(that)
        }
    };

    getName.newBind(obj)() //joy
  • 再优化一下
    const obj = {
        name:'joy'
    };

    function getName(){
        console.log(this.name);
    }

    Function.prototype.newBind = function (that) {
        if (typeof this !== 'function') {
            throw new TypeError('Error')
        }
        const args = [...arguments].slice(1);
        const fn = this;
        return function () {
            fn.apply(that)
        };
        // 返回一个函数
        return function F() {
            // 因为返回了一个函数,如果是new的话this就要指向新创建的对象了
            if (this instanceof F) {
                return new fn(...args, ...arguments)
            }
            return fn.apply(that, args.concat(...arguments))
        }
    };

    getName.newBind(obj)() //joy

以上就是实现call,apply,bind的内容了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • this 的指向 在 ES5 中,其实 this 的指向,始终坚持一个原理:this 永远指向最后调用它的那个对象...
    fenerchen阅读 690评论 0 9
  • 关于 this this 关键字是 JavaScript 中最复杂的机制之一。它是一个很特别的关键字,被自动定义在...
    游学者灬墨槿阅读 669评论 1 2
  • JavaScript(面向对象+原型理解+继承+作用域链和闭包+this使用总结) 一、面向对象 1、什么是面向对...
    老头子_d0ec阅读 344评论 0 0
  • 之前从第一点到第七全部在本公众号上进行了全部的更新,而这7个点一个活动都具备了的情况下会最大机率提高活动的成功率,...
    51运营阅读 692评论 0 1
  • 什么是机器人 首先,对于机器人的释义,我认同以下两个观点: “机器人不是人,没有必要在形体、功能、感官上像人一样。...
    大补丸阅读 892评论 0 3

友情链接更多精彩内容