使用原生JS实现call()、aply()、bind() 函数

本文详细介绍了JavaScript中call、apply和bind函数的区别,并分别实现了这三个方法。call和apply的主要区别在于参数传递形式,call接受可变数量的参数,而apply参数是一个数组。bind则不同,它不会立即调用函数,而是返回一个新函数,新函数的this绑定到bind的第一个参数,后续参数预设在新函数调用时传递。
摘要由CSDN通过智能技术生成

前提知识回顾:call()、apply()、bind()函数之间的区别

实现call()方法

解题思路:首先我们要知道使用call函数的一些规定

  • 调用的call()方法的是函数
  • 如果指定的this值null或者undefined,则会自动指向全局对像(浏览器中就是window对象)
  • 如果指定的this值为数字,字符串,布尔值等,则会指向原始值的实例对象
    Function.prototype.myCall = function(context){
        if(typeof this != 'function'){
            throw new TypeError('Error')
        } //判断调用该方法的是不是函数,如果不是,则抛出异常
        if(context === null || context === undefined){
            context = window //指定为null 和 undefined 的 this值会自动指向全局对象(浏览器中为windiw)
        } else {
            context = Object(context) //值为数字,字符串,布尔值等的this 会指向原始值的实例对象
        }
        // 给context添加一个属性
        context.fn = this
        //剩余运算符,得到的是一个数组,包含除了this值的其他参数
        // 通过参数伪数组将context后面的参数取出来
        let args = [...arguments].slice(1)
        // 调用该函数
        let result = context.fn(...args);
        // 删除fn
        delete context.fn
        // 返回结果
        return result
    }

实现apply()方法

apply()方法和call()方法类似,只是参数的形式不一样

因为apply()方法的参数是一个数组或者类数组对象,所以需要判断是否存在第二个参数,如果存在就将第二个参数也展开,如果不存在直接调用该方法

    Function.prototype.myApply = function (context) {
        if (typeof this !== 'function') {
            throw new TypeError('Error')
        }
        //判断调用该方法的是不是函数,如果不是,则抛出异常
        if (context === null || context === undefined) {
            context = window     // 指定为 null 和 undefined 的 this 值会自动指向全局对象(浏览器中为window)
        } else {
            context = Object(context) // 值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的实例对象
        }
        // 给context添加一个属性
        context.fn = this
        var  result = null 
        //判断是否存在第二个参数
        //如果存在就将第二个参数也展开
        // 如果不存在直接调用该方法
        if(arguments[1]) {
            result = context.fn(...arguments[1])
        } else {
            result = context.fn()
        }
        delete context.fn
        return result
    }

实现bind()方法

bind 和 call/apply 有一个很重要的区别,一个函数被 call/apply 的时候,会直接调用,但是 bind 会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。

Function.prototype.mybind = function (context) {
        if (typeof this !== 'function') {
            throw new TypeError('Error')
        }
        // 保存需要绑定的this上下文
        const _this = this
        // 取参数 
        const args = [...arguments].slice(1)
        //返回一个改变了this指向的新的函数
        return function F () {
            if (this instanceof F) { 
            // this是否是F的实例 也就是返回的F是否通过new调用
            //利用扩展运算法合并数组
                return new _this(...args, ...arguments)
            }
            return _this.apply(context,args.concat(...arguments))
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值