这里介绍的是ES6之前的继承方式,没有写 class 继承哦。
什么是继承
继承是指一个对象直接使用另一对象的属性和方法。
js中继承的方法有:原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生式组合继承
1. 原型链继承
(1). 原型、构造函数和实例的关系
function Person() { } Person.prototype var p = new Person();
构造函数:Person
属性:prototype => 指向原型对象
原型对象:Person.prototype
属性:constructor => 指向构造函数
原型、构造函数和实例的关系:
出现上面那个结果的原因是,实例是没有constructor这个属性的,p.constructor其实是访问的p.prototype.constructor,但是由于我们用对象字面量的方式重写了Person.prototype,所以会顺着原型链往上找,找到
Object.prototype.constructor.
(2). 原型链
如(1)中所示,如果让(1)中的原型对象成为另外一个类型的实例,以此类推,便构成了原型链。
注意:所有构造函数的默认原型都是Object的实例,因此默认原型会有一个prototype指针指向Object.prototype。
(3). 原型链继承
主要思想是:通过设定一种类型的原型是另一种类型的实例来继承另外一种类型。
例如:B要继承A
创建A的实例:new A();
让其等于B的原型:B.prototype = new A(); //B则继承了A里面所有的属性和方法
原型搜索机制:以读取方式访问一个实例属性时,在该实例中搜索该属性,若没有找到再搜索实例的原型,顺着原型链往上找。
代码示例如下:
原型继承的缺点:
(1).超类型中有引用类型(color是一个数组)的属性时,子类型继承超类型,一个子类型中对该引用类型修改,会反应到所有的子类型上。所有子类型共享超类型的引用类型.
例如:
(2).创建子类型实例时无法向超类型的构造函数中传递参数
2. 构造函数继承
利用call()和Apply()方法在新的对象上执行超类型的构造函数。
超类型:指的是被继承的类型。
a.func.call(b) /*指的是a对象的方法应用到b对象上*/ a.func.apply(b) // 主要是参数的区别
代码示例:
构造函数继承的优点:
使子类Child在创建对象的同时传递参数到父类Parent
构造函数继承的缺点:
无法进行函数的复用,a的原型中定义的方法也无法继承。
3. 组合继承(将原型链继承和借用构造函数继承组合起来)
主要思想是:使用原型链实现对a原型属性和方法的继承,通过构造函数实现对a实例属性的继承。
代码示例如下:
缺点:要调用两次超类型的构造函数(注释的两个地方)
4. 原型式继承
主要思想是:实现对父类的浅复制,产生一个副本
Object.create()函数实现的就是原型式继承
代码示例如下:
这种继承方式是将child的原型设为parent,通过child可以访问parent的属性和方法,而不需要将同名属性和方法在child里面再重新定义一遍。
Object.create() 可接收两个参数,第一个参数是需要继承的对象,第二个参数是新生成的对象中新增加的属性和方法。
5. 寄生式继承
主要思想:寄生式继承是基于原型式继承,创建一个仅用于封装继承的函数
代码示例如下:
欢迎关注。