1

带着以下几个问题:
1、call 和 apply 的区别在哪?
2、call 在什么情况下使用? apply 在什么情况下使用?
3、apply 有哪些妙用?

apply 和 call 都可以劫持另外一个对象的方法,继承另外一个对象的属性,下面我们看一些他们的不同在哪里;
下面看代码是如何体现的:

Function.apply(obj, arguments)方法能接收两个参数
obj:这个对象的 this 指向将代替Function类里this指向
arguments:这个是数组,它将作为参数传给Function(args-->arguments)

apply 示例:

    function Person(name, age) {
        this.name = name;
        this.age = age;
    }

    function Boy(name, age, job) {
        Person.apply(this, arguments);
        this.job = job;
    }

    const boy = new Boy('Phoenix', 27, 'programmer');

    console.log(boy.name, boy.age, boy.job);   // Phoenix 27 programmer

上面代码中 Boy 构造函数中,我们并没有构造 name 和 age 参数;
但是实例化对象 boy 中还是有完整的三个参数,这就是 apply 的魅理。

call 示例:

    function Person(name, age) {
        this.name = name;
        this.age = age;
    }

    function Boy(name, age, job) {
        Person.call(this, name, age);
        this.job = job;
    }

    const boy = new Boy('Phoenix', 27, 'programmer');

    console.log(boy.name, boy.age, boy.job);   // Phoenix 27 programmer

上面的 Boy 中的name 和 age 参数指向的都是 Person 中的 name 和 age 参数;
由上面两个示例可以发现 call 和 apply 的区别仅仅在于参数形式不同;
apply方法的第二个参数是由参数组成的数组;
而call方法的第二个参数则是被展开的数据,在ES6中也可以是 Function.call(this, ...arguments),效果一样;


那么 apply 方法都有哪些方便的功能呢;
(1)Math.max() 这个方法会在所有的参数中查找到最大的一个;

Math.max(1, 2, 3)   // 3

如果这个方法如果这可以这样使用那真是太鸡肋了;
如果他能传递一个数组,我们在数组中查找到最大的数字那不是很好用吗?

const arr = [1, 2, 3];
Math.max.apply(null, arr)    // 3
// 当然 ES6 出现以后 有了展开运算符 ... 可以获得一样的结果
Math.max(...arr);    // 3

当然apply方法不只是这一个地方用的到
加入我们想把两个数组整合到一起;
(2)Array.prototype.push.apply(arr1, arr2);

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1);    // [1, 2, 3, 4, 5, 6]
// ES6 以后 
// arr1.push(...arr2)   效果一样 

其实在 ES6 出现以后,好多以往被 apply 可以展开运算的功能基本都被 ...展开运算符代替了;

总结:

大家从上面可以学习到 apply 和 call 的用法,也尝到了ES6中的甜,但也不要忘记以前但知识哦,语法糖但实现原理也都是源于老版本的JS,基础尤为重要!

Milo
7 声望3 粉丝

to yound to simple.