• 58.call、apply以及bind函数内部实现是怎么样的


    call, apply, bind的内部实现原理   https://www.cnblogs.com/renzhiwei2017/p/10364760.html

     

    call, apply, bind都是改变函数执行的上下文,说的直白点就是改变了函数this的指向。不同的是:call和apply改变了函数的this,并且执行了该函数,而bind是改变了函数的this,并返回一个函数,但不执行该函数。

    看下面的例子1:

    var doThu = function(a, b) {
        console.log(this)
        console.log(this.name)
        console.log([a, b])
    }
    var stu = {
        name: 'xiaoming',
        doThu: doThu,
    }
    stu.doThu(1, 2) // stu对象 xiaoming [1, 2]
    doThu.call(stu, 1, 2) // stu对象 xiaoming [1, 2]
    

    由此可见,在stu上添加一个属性doThu,再执行这个函数,就将doThu的this指向了stu。而call的作用就与此相当,只不过call为stu添加了doThu方法后,执行了doThu,然后再将doThu这个方法从stu中删除。

    下面来看call函数的内部实现原理:

    Function.prototype.call = function(thisArg, args) {
        // this指向调用call的对象
        if (typeof this !== 'function') { // 调用call的若不是函数则报错
            throw new TypeError('Error')
        }
        thisArg = thisArg || window
        thisArg.fn = this   // 将调用call函数的对象添加到thisArg的属性中
        const result = thisArg.fn(...[...arguments].slice(1)) // 执行该属性
        delete thisArg.fn   // 删除该属性
        return result
    }
    

    apply的实现原理和call一样,只不过是传入的参数不同而已。下面只给出代码,不做解释:

    Function.prototype.apply = function(thisArg, args) {
        if (typeof this !== 'function') { 
            throw new TypeError('Error')
        }
        thisArg = thisArg || window
        thisArg.fn = this
        let result
        if(args) {
            result = thisArg.fn(...args)
        } else {
            result = thisArg.fn()
        }
        delete thisArg.fn
        return result
    }
    

    bind的实现原理比call和apply要复杂一些,bind中需要考虑一些复杂的边界条件。bind后的函数会返回一个函数,而这个函数也可能被用来实例化:

    Function.prototype.bind = function(thisArg) {
        if(typeof this !== 'function'){
            throw new TypeError(this + 'must be a function');
        }
        // 存储函数本身
        const _this  = this;
        // 去除thisArg的其他参数 转成数组
        const args = [...arguments].slice(1)
        // 返回一个函数
        const bound = function() {
            // 可能返回了一个构造函数,我们可以 new F(),所以需要判断
            if (this instanceof bound) {
                return new _this(...args, ...arguments)
            }
            // apply修改this指向,把两个函数的参数合并传给thisArg函数,并执行thisArg函数,返回执行结果
            return _this.apply(thisArg, args.concat(...arguments))
        }
        return bound
    }
    
     
  • 相关阅读:
    JavaWeb(二)会话管理之细说cookie与session
    JavaWeb(一)Servlet中乱码解决与转发和重定向的区别
    JavaWeb(一)Servlet中的request与response
    JavaWeb(一)Servlet中的ServletConfig与ServletContext
    JavaWeb(一)之细说Servlet
    OOAD-设计模式(一)概述
    异常处理升级版
    MySQL优化原理
    hadoop 有那些发行版本
    centos7 安装搜狗输入法
  • 原文地址:https://www.cnblogs.com/dream111/p/13472771.html
Copyright © 2020-2023  润新知