apply()与call()方法详解

无需原生开发基础,也能完美呈现京东商城。《混合开发京东商城系统,提前布局大前端》课程融合vue、Android、IOS等目前流行的前端和移动端技术,混合开发经典电商APP——京东。课程将各种复杂功能与知识点完美融合,从技术原理到开发上线,让你真实感受到一个明星产品开发的全过程。功能实现之外,还有一流用户体验和优秀交互设计等你一探究竟,拓宽开发眼界。


在JS的每个函数之中,都包含两个非集成而来的方法apply()和call()。这两个方法的用途都是在特定的作用域中调用函数,等于设置函数体内this对象的值
两个方法唯一的区别是接受的参数不同appay()方法接受运行函数的作用域和数组,call()方法接受运行函数的作用域和直接调用函数的参数 看下面的例子

// 声明一个方法sum作为调用apply和call方法的函数
        function sum (a , b) {
            console.log(a + b);
        }
        
        // 调用apply方法传入一个数组
        function callSum1 (a, b) {
            sum.apply(this, [a, b]);
        }

        // 调用apply方法传入arguments对象,其实也是一个数组
        function callSum2 (a, b) {
            sum.apply(this, arguments);
        }

        // 调用call方法传入sum方法需要的参数 a, b
        function callSum3 (a, b) {
            sum.call(this, a,b);
        }

然后我们分表调用 callSum1 ,callSum2 ,callSum3这三个函数

callSum1(1, 1);
// 2
callSum2(1, 1);
// 2
callSum3(1, 1);
// 2

得到的打印结果相同。
我们来回顾一下apply和call方法的定义
在特定的作用域中调用函数,等同于

function callSum1 (a, b) {
	//sum.apply(this, [a, b]);
    console.log(a + b);
}

这样看或许不是很直观,让我们来看下面这个例子

// 定义一个全局变量name:javascript
        var name = 'javascript';

        // 定义一个对象android, 他的name为 android
        var android = {
            name: 'android'
        }

        // 定义一个方法ios, 他的name为 ios (在javascript中 function也是对象)
        var ios = function () {
            this.name = 'ios';
        }

        // 输出name的值
        function consoleName () {
            console.log(this.name);
        }

然后我们这样去调用它

 consoleName.call(window);   // javascript
 consoleName.call(this);   // javascript
 consoleName.call(android);     // android
 consoleName.call(ios);   // undefined

我们可以发现前三个调用都符合我们的预期,在特定的作用域内调用函数,等于改变了函数体内this对象的值 相当于我们把方法consoleName放到了指定的作用域中,然后在指定的作用域中调用了他,相当于如下代码。

consoleName.call(window);
 // window.consoleName = function () {
 //     console.log(this.n);
 // }
 //  window.consoleName();

 consoleName.call(this);
 // window.consoleName = function () {
 //     console.log(this.n);
 // }
 //  window.consoleName();

 consoleName.call(android);
//	var android = {
 //           n: 'android',
 //           consoleName: function () {
 //               console.log(this.n);
 //           }
 //       }
 // android.consoleName();

但是为什么再去调用 consoleName.call(ios);的时候会打印 undefined那?我们关注一下ios的定义

var ios = function () {
    this.n = 'ios';
}

consoleName.call(ios);
// var ios = function () {
//            this.n = 'ios';
//            consoleName: function () {
//                console.log(this.n);
//           }
//        }

看出来了吗? 我们等于给方法添加了一个属性,那对于ios这种我们应该怎么做那? 看一下修改之后的代码

// 标记Ios为一个构造函数
        var Ios = function () {
            this.n = 'ios';
        }
// 创建Ios对象,相当于我们在Ios的对象之中调用了consoleName方法,把consoleName的this指向了Ios的对象
 consoleName.call(new Ios());

打印结果 符合预期

你可能感兴趣的:(apply()与call()方法详解)