关于继承apply和call的区别以及apply的巧妙用法

655 阅读3分钟

最近涉及到使用原生JS,又把继承,闭包,原型,作用域链过了一遍,有一些新的认识,在此记录一哈0.0

首先,什么是继承?

所谓继承就是在两个构造方法间建立起来的某种关系,通过这种关系,就能够让下级构造方法创建出来的实例享用上级构造方法获取原型对象中的内容。注意JS(ES5)中没有专门用于继承的语法。我们可以采用如下方式实现继承:借用构造方法继承(无法继承原型中的内容)、原型链继承、组合继承。这次要说的apply和call属于构造方法继承。

先写个apply和call在继承时的例子(真的没有ES6好用)

 // 人的构造方法
        function Person(Name, age, gender) {
            this.Name = Name;
            this.age = age;
            this.gender = gender;
        }
        //学生的构造方法
        function Student(Name, age, gender, subject) {
            // 借用Person的功能实现对name、age、gender属性的初始化操作
            Person.call(this, Name, age, gender);//call实现
             Person.apply(this, [Name, age, gender]);//apply实现
            this.subject = subject;
        }

        var p1 = new Person('Tom', 10, '男');
        var s1 = new Student('小明', 5, '男', '英语');

        console.log(p1);
        console.log(s1);
        

这样就可以得到有两个构造方法创建的两个实例:

{Name:'Tom',age:10,gender:'男'}
{Name:'小明',age:5,gender:'男',subject:'英语'}

好,现在Student的Name,age,gender就是继承的Person构造方法的。

call和apply使用时的区别

我们已经知道call和apply都可以实现构造方法继承,但是他们的适用场景有什么不同呢?

如果说,我们给定参数是数组类型,并且参数的顺序是一致的,那么这时候我们可以使用apply;

如果我们的参数列表不一致,比如说Person是(Name,age),但是我们的Student是(age,Name,gender),这时候我们就得使用call来实现,直接指定他的位置Person.call(this,age,Name,gender)

apply扩展

我们知道,当我们使用apply方法时,它的格式是Person.apply(this,[Name,age,gender]),但是当我们在调用Person时,他需要的并不是一个数组,根据这一点,我们可以知道,apply有一个特性,他可以将[Name,age,gender]转化为(Name,age,gender),看到这里想到了什么?

记得之前看Math的时候有个拿到一堆数中的最大最小值的方法,Math.max().Math.min(), 但是难受的是他们的参数不能是数组,只能是这样Math.max(1,2,3,4),看到这个当时认为这个方法很鸡肋,但是接触apply之后发现了一个新世界。既然apply可以把数组转化成(1,2,3,4)的形式,那么用在这里岂不是很舒服?

比如说我们要拿到一个数组中的最大值,[1,3,5,7,2,4,9,6]

 var arr=[1,3,5,7,2,4,9,6]
        let max=Math.max.apply(null,arr)
        console.log(max) //9

这样可以轻松拿到数组中的最大值,而不需要使用for循环去遍历比较,或者使用冒泡排序。当然说的之是一种思想,毕竟冒泡很香。

//sort()排序
var arr=[1,3,5,7,2,4,9,6]
        arr.sort((a,b)=>{
            return a-b
        })
        console.log(arr)//[1, 2, 3, 4, 5, 6, 7, 9]

小结,很多东西再次回顾总会有新的发现,但是该说不说,ES6,7,8的技术真的在降低编程难度,封装性越来越强。

有写的不清楚的地方还请不吝赐教0.0,祝大家在写代码的道路上越走越远=-=