这是面试时面试官会经常问到问题:
js的继承方式大致可分为两种:对象冒充和原型方式;
一、先说对象冒充,又可分为3种:临时属性方式、call()、apply();
1、临时属性方式:
当构造对象son的时候,,调用temp相当于启动Person的构造函数,值得注意的是,这里上下环境中的this对象是son的实例,所以在执行person的构造函数脚本时,所有person的变量及函数都会赋值给this所指的对象,也就是son的实例,这样就达到了son继承person的属性和方法的目的。而之后删除临时引用的temp,是防止维护son中对person的类对象(不是实例对象)的引用更改,因为更改temp会导致类person(注意不是类person的对象)的及结构变化。
2、call()方法:
该方法也是通过改变this指向达到继承的目的,是function中定义的方法,所以我们定义的每一个函数都有这个方法;
通过该方法改变了this指向,调用了person里的方法;原理同临时属性方式相似;
也可以这么写:
第一个参数是simon,说明应该赋予say()函数中的this关键字值是simon;
之后的参数是字符串与person的参数的匹配值。
3、apply()
原理与call()一样,也是function中的方法,用法也与call类似:只是参数传入的形式为数组;
面试时常会问道call与apply的区别,这点值得注意。
二、原型链继承
这点涉及到了对象的原型链相关知识,指利用了prototype或者说以某种方式覆盖了prototype,从而达到属性方法复制的目的。其实现方式有很多中,可能不同框架多少会有一点区别,但是我们把握住原理,就不会有任何不理解的地方了。
原型链方法说的简单点就是将person函数当成son函数的原型对象,利用原型对象中的属性与方法是可以继承的这个属性,变相的继承person中的方法。
蛋值得注意的是,原型链方法是不可以传参数的,要想传参,则要与call或者apply混合使用。
三、优缺点
call/apply:优:1、可以实现多重继承 2、可以初始化继承自父类的参数;
缺:浪费内存资源,所有的实例都会拥有一份成员方法的副本;
原型链继承:用子类构造函数的参数去初始化父类属性是无法实现的。
以上是我在学习过程中,对各种资料总结后的个人认识,如过有不恰当或者错误的地方,请留言指正,谢谢啦~