高程笔记-对象2

《JavaScript高级程序》笔记,主要关于对象的继承。

原型链继承

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。参考高程,其基本的关系如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
}
function SubType() {
this.subproperty = false;
}
// 继承了SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function() {
return this.subproperty;
}

var instance = new SubType();
console.log(instance.getSuperValue()); //true

原型链

由关系图也能看出,实例与构造函数是没有直接关系的。这点在后面的继承关系中很重要。

可以通过instanceof来判断原型与实例之间的关系。同时也可以通过isPrototypeOf()来判断是否为原型链所派生的实例的原型。

1
2
3
4
5
6
7
console.log( instance instanceof Object )    //true
console.log( instance instanceof SuperType ) //true
console.log( instance instanceof SubType ) //true

console.log( Object.prototype isPrototypeOf(instance) ) //true
console.log( SuperType.prototype isPrototypeOf(instance) ) //true
console.log( SubType.prototype isPrototypeOf(instance) ) //true

缺点:原型链在创建对象的时候已经体现出来。当出现引用类型时,会影响其它实例。

借用构造函数

未解决引用类型的问题,出现了借用构造函数(伪造对象/经典继承)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function SuperType() {
this.colors = ['red','blue','green']
}
function SubType() {
//继承SuperType
SuperType.call(this)
}

var instance1 = new SubType();
instance1.colors.push('black');
console.log(instance1.colors); //'red,blue,green,black'

var instance2 = new SubType();
console.log(instance2.colors); //'red,blue,green'

缺点:方法都在构造函数中定义,函数不能复用。

组合继承

也叫伪经典继承。即组合原型链和借用构造函数的方法。

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
27
28
29
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;
}
// 继承方法
SubType.prototype = new SuperType();

SubType.prototype.sayAge = function() {
alert(this.age);
}

var instance1 = new SubType('jon',29);
instance1.colors.push('black');
console.log(instance1.colors); //'red,blue,green,black'
console.log(instance1.name); //jon
console.log(instance1.age); //29

var instance2 = new SubType('snow',20);
console.log(instance2.colors); //'red,blue,green'
console.log(instance2.name); //snow
console.log(instance2.age); //20

缺点:继承重复掉用父类。

原型式继承

道格拉斯·克罗克福德的方法。通过辅助函数实现浅复制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function object(o) {
function F(){}
F.prototype = o;
return new F();
}

var person = {
name: 'jon',
friends: ['Shelty','Count','Van']
};
var anotherPerson = object(person);
anotherPerson.name = 'snow';
anotherPerson.friends.push('Rob');

var yetAnotherPerson = object(person);
yetAnotherPerson.name = 'Linda';
yetAnotherPerson.friends.push('Sarbie');

alert(person.friends); // 'Shelty','Count','Van','Rob','Sarbie'

同es5的Object.create()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
var person = {
name: 'jon',
friends: ['Shelty','Count','Van']
};
var anotherPerson = Object.create(person);
anotherPerson.name = 'snow';
anotherPerson.friends.push('Rob');

var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = 'Linda';
yetAnotherPerson.friends.push('Sarbie');

alert(person.friends); // 'Shelty','Count','Van','Rob','Sarbie'

寄生式继承

1
2
3
4
5
6
7
8
9
10
11
12
13
function object(o) {
function F(){}
F.prototype = o;
return new F();
}

function createAnother(original) {
var clone = object(original);
clone.sayHi = function() {
alert('hi');
}
return clone;
}

寄生组合式继承

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
27
28
29
function object(o) {
function F(){}
F.prototype = o;
return new F();
}
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() {
alert(this.age);
}
------本文结束 感谢阅读------