文章目录
JS无法像其他高级语言那样通过extend直接实现继承。只通过一定方式来实现继承机制。常见的几种实现继承的方式有:
- 对象冒充
- call/apply方法
- 原型链(prototype chain)
- 混合方式(call/apply+prototype chain)
1. 对象冒充
父类:
1 | function superClass(name){ |
子类:
1 | function subClass(name) |
这种方式的缺点有1.需额外添加一个属性;2.无法使用父级原型的拥有的属性
注意:子类的独自拥有的属性应该放在最后,以防止父类的属性覆盖了
对象冒充可以实现多重继承:
1 | function ClassZ() { |
2. call/apply方法
父类:
1 | function superClass(name){ |
子类:
1 | function subClass(name){ |
这种实现方式的缺点是无法继承来自父级原型的属性
3. 原型链(prototype chain)
父类:
1 | function superClass(name){ |
子类:
1 | function subClass(){ |
使用firebug打印对象subObj信息:console.dir(subObj)
程序原意将name属性设为’it is subobj’但没有起作用。这是因为要调用父类,必须在设置原型的时候调用。即subClass.prototype=new superClass(name)
但属性较多的情况下,就过于麻烦了。解决办法就是下面将讲的混合方式实现继承
在讲混合方式实现继承之前,我们先来了解一下对象继承关系和属性来源判断
子类对象既是子类的实例也是父类的实例也是Object的实例。任何应用类型默认继承了Object.所有函数的默认都是Object的实例
1 | console.log(subObj instanceof superClass)=== true |
通过过in
和hasOwnPropertype
能判断属性的来源
1 | if(property in object){ |
如果对象的属性与其原型的属性同名,则原型的属性会被屏蔽但不会覆盖,如果delete操作后,对象的属性将使原型的属性值
1 | function superClass(){ |
4. 混合方式(call/apply+prototype chain)
父类:
1 | function superClass(name) |
子类:
1 | function subClass(name){ |
问:为什么会添加最后一句?使用superClass.apply(this,arguments);不就行了吗?
答:如果只使用superClass.apply(this.arguments)则使用父类的构造函数。但是无法继承了父类的原型属性,即extendInfo属性。