JavaScript中call和apply的原理

109 阅读1分钟

call方法

call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。 语法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,应用某一对象的一个方法,用另一个对象替换当前对象。

说明: call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。

apply方法

apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。 语法:apply([thisObj [,argArray] ]);,调用一个对象的一个方法,2另一个对象替换当前对象。

说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个 TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。

call原理

  // //  1.call原理
        function fn(a, b, c) {
            return {
                name: this.name,
                a,
                b,
                c
            }
        }
        Person = {
            name: '张三'
        }

        // fn.call(Person)
        // call函数内部原理
        Function.prototype.newCall = function(obj) {
           
            obj = obj || window
            obj.p = this
            // console.log(obj.p);
            //参数部分
            var newArguments = []
            for (var i = 1; i < arguments.length; i++) {
                newArguments.push('arguments[' + i + ']')
            }
            console.log(newArguments);
            //eval有点问题 不太懂
            var res = eval('obj.p(' + newArguments + ')')
            console.log('obj.p(' + newArguments + ')');
            delete obj.p
            return res
        }
        console.log(fn.newCall(Person, '你好', '我好', '大家好'));

apply原理

 // 2.apply原理
        function fn(a, b, c) {
            return {
                name: this.name,
                a: a,
                b: b,
                c: c
            }
        }
        var Person = {
            name: '张三'
        }
        Function.prototype.newApply = function(obj, arr) {
            var obj = obj || window,
                res;
            obj.p = this
            if (!arr) {
                res = obj.p()
            } else {
                var newArguments = []
                for (var i = 0; i < arr.length; i++) {
                    newArguments.push('arr[' + i + ']')
                }
                res = eval('obj.p(' + newArguments + ')')
            }
            delete obj.p
            return res
        }
        console.log(fn.newApply(Person, ['你好', '我好', '大家好']));

以上是JavaScript中Function的中的call方法和apply方法的简单实现。另外bind()方法和call()类似,差别就在于使用call的时候会自动调用方法,而bind不会