zoukankan      html  css  js  c++  java
  • 【javascript】手写call,apply,bind函数

    考虑两点:

    • 第一个参数为undefined或null的时候,那么会转变为window
    • 改变了this执行,让新的对象可以执行该函数。

    call

    Function.prototype.myCall = function(context) {
        if (typeof context === "undefined" || context === null) {
            context = window
        }
       //context=context||window  和上面的代码一样
        context.fn = this//(因为call的调用方式形如:myFun.call(obj),因此此时call方法的this指向为myFun,因此context.fn = this即为context.fn = myFun)
        const args = [...arguments].slice(1)//第一个参数为context,要去除
        const result = context.fn(...args)
        delete context.fn
        return result
    }

    实现分析

    • 首先context为可选参数,如果不传的话默认上下文是window
    • 接下来给content创建一个fn属性,并将值设置为需要调用的函数
    • 因为call可以传入多个参数作为调用函数的参数,所有需要将参数剥离出来
    • 然后调用函数并将对象上的函数删除

    apply

    apply和call实现类似,不同的就是参数的处理

    Function.prototype.myApply = function(context) {
        if (typeof this !== 'function') {
            throw new TypeError('Error')
        }
        context = context || window
        context.fn = this
        let result
        if (arguments[1]) {
            result = context.fn(...arguments[1])
        } else {
            result = context.fn()
        }
        delete context.fn
        return result
    }

    bind

    因为bind转换后的函数可以作为构造函数使用,此时this应该指向构造出的实例,而不是bind绑定的第一个参数

    Function.prototype.myBind = function(context) {
        if (typeof this !== 'function') {
            throw new TypeError('Error')
        }
        //返回一个绑定this的函数,这里我们需要保存this
        const _this = this
        const args = [...arguments].slice(1)
            //返回一个函数
        return function F() {
            //因为返回一个函数,我们可以new F()需要判断能当做构造函数吗
            if (this instanceof F) {
                return new _this(...args, ...arguments)
            }
            return _this.apply(context, args.concat(...arguments))
        }
    }
    • bind返回一个函数,对于函数来说有两种方式调用,一种是直接调用,一种是通过new的方式,我们先来说直接调用的方式
    • 对于直接调用来说,这里选择了apply的方式,但是对于参数需要注意以下情况:因为bind可以实现类似这样的代码 f.bind(obj,1)(2),所以我们需要将两边的参数拼接起来,于是就有了这样的实现args.concat(…arguments)
    • new的方式,我们先判断this,对于new的情况,不会被任何方式改变this,所以对于这种情况我们需要忽略传入的this

    转自:https://blog.csdn.net/qq_37288477/article/details/87884518

  • 相关阅读:
    浩秦的竞聘报告
    烽火2640路由器命令行手册-14-桥接配置命令
    烽火2640路由器命令行手册-13-VPDN(L2TP,PPTP,PPPOE)配置命令
    烽火2640路由器命令行手册-12-IBM网络配置命令
    烽火2640路由器命令行手册-11-IP语音配置命令
    烽火2640路由器命令行手册-10-可靠性配置命令
    烽火2640路由器命令行手册-09-拨号配置命令
    烽火2640路由器命令行手册-08-服务质量配置命令
    烽火2640路由器命令行手册-07-安全配置命令
    烽火2640路由器命令行手册-06-组播协议配置命令
  • 原文地址:https://www.cnblogs.com/vickylinj/p/14427534.html
Copyright © 2011-2022 走看看