JavaScript中的继承

JavaScript中的继承

JavaScript中的继承主要使用原型链实现
1.原型继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var SuperType = function () {
this.property = true
}
SuperType.prototype.getSuperValue = function () {
return this.property
}
var SubType = function () {
this.property = false
}
SubType.prototype = new SuperType()

var instance = new SubType()

instance.getSuperValue()
// false
instance instanceof Object
// true
instance instanceof SuperType
// true
instance instanceof SuberType
// true

优点:实现了继承
缺点:实例之间的属性共享问题
2.借用构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var Person = function (name) {
this.name = name
this.friends = ['tom', 'petter', 'li']
}
Person.prototype.sayName = function () {
console.log(this.name)
}
var Parent = function (name) {
Person.call(this, name)
}

var instance0 = new Parent('tony')
var instance1 = new Parent('bruce')

instance0.friends
// ['tom', 'petter', 'li']
instance1.friends
// ['tom', 'petter', 'li']

instance0.friends.push('bob')
instance1.friends.push('bill')

instance0.friends
// ['tom', 'petter', 'li', 'bob']
instance1.friends
// ['tom', 'petter', 'li', 'bill']

优点:实例之间的属性可以独立
缺点:实例之间的方法无法复用

3.组合继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var Person = function (name) {
this.name = name
this.friends = ['tom', 'petter', 'li']
}
Person.prototype.sayName = function () {
console.log(this.name)
}
var Parent = function (name, age) {
Person.call(this, name)
this.age = age
}

Parent.prototype = new Person()
Parent.prototype.constructor = Person
Parent.prototype.sayAge = function () {
console.log(this.age)
}

优点:不同的实例拥有各自的属性和相同的方法
缺点:调用两次构造函数

4.原型式继承
这是一种借助已有对象来进行继承的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function object (o) {
function F () {}
F.prototype = o
return new F()
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
}
var anotherPerson = object(person)
var yetAnotherPerson = object(person)

anotherPerson.name = "Greg"
anotherPerson.friends.push("Rob")
yetAnotherPerson.name = "Linda"
yetAnotherPerson.friends.push("Barbie")
person.friends
// Shelby,Court,Van,Rob,Barbie

ECMAScript 5 新增 Object.create() 规范化原型式继承
优点:使用方便
缺点:使用属性的值会共享

5.寄生式继承
寄生式继承和寄生构造函数一样,都是在函数的内部对实例进行增强

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var createAnother = function (original) {
var clone = Object.create(original)
clone.sayHello = function () {
console.log('hello')
}
return clone
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person)
anotherPerson.sayHello()
// hello

6.寄生组合继承
组合继承存在调用两次父类的构造函数问题这会时父类的原型上创建出多余的属性 解决的方案是 我们只需要父类原型一个拷贝 没有必要调用父类的构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function inheritPrototype(subType, superType){
var prototype = object(superType.prototype)
prototype.constructor = subType
subType.prototype = prototype
}
function SuperType(name){
this.name = name
this.colors = ["red", "blue", "green"]
}
SuperType.prototype.sayName = function(){
alert(this.name)
}
function SubType(name, age){
SuperType.call(this, name)
this.age = age
}
inheritPrototype(SubType, SuperType)
SubType.prototype.sayAge = function(){
console.log(this.age)
}

优点: 完美了

以上