Js原型链与继承

一、基本概念

原型链是ESMAScript实现继承的主要方法,基本思想是让一个引用类型继承另一个引用类型的属性和方法。其中的主要内容分以下几点:

1 构造函数与原型对象

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,以下面的代码为例:

function SuperType() {
    this.property = true;
}

console.log(SuperType.prototype.constructor === SuperType); // ture

在上面的例子中构造函数SuperType有一个原型对象,使用SuperType.proptype可以得到,这个对象有一个constructor属性,指向构造函数的SuperType对象。此处要注意一个问题,通过构造函数创建的实例没有原型对象,但是其有一个指向原型对象的内部指针,如下代码所示:

function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function () {
    return this.property;
};

var instance = new SuperType();
console.log(instance.prototype);    // undefined
console.log(instance.getSuperValue());     // ture

从上面的例子可以看到实例instance.prototype是不存在的,但instance.getSuperValue()调用时,首先会搜索实例中是否有此属性,没有此属性后再通过指向原型对象的内部指针找到对应的属性,得到getSuperValue()。

2 继承的实现

如果让一个构造函数的原型对象等于另一个类型的实例,那么此时的原型对象将包含一个指向另一个原型的指针(此指针也为内部指针)即实现了继承。通过代码来说明:

function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function () {
    return this.property;
};

function SubType() {
}

// 继承了SuperType
SubType.prototype = new SuperType();

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

上面的代码中instance为SubType的一个实例,SubType继承了SuperType所以调用时会通过原型链找到SuperType的prototype对象,得到里面的getSuperValue属性并调用函数返回ture。

二、原型链中的注意问题

1 包含引用类型值的原型

因为包含引用类型值的原型属性会被所有实例共享,而通过原型来实现继承时,原型实际上会变成另一个类型的实例,通过代码来解释:

function SuperType() {
    this.colors = ['red', 'blue'];
}

SuperType.prototype.getSuperValue = function () {
    return this.colors;
};

function SubType() {
}

SubType.prototype = new SuperType();

var instance = new SubType();
instance.colors.push('yellow');
console.log(instance.getSuperValue());  // ['red','blue','yellow']
console.log(SubType.prototype.colors);  // ['red','blue','yellow']

在这里,SubType继承了SuperType,继承后SubType的原型对象SuperType的一个实例,即SubType的原型对象SubType.prototype对象有colors属性。在之后向此color中加入’yellow’,即可看到colors新加入了一个元素。

2 默认的原型Object

所有引用类型都默认继承了Object,也就是所有的函数的默认原型都是Object的实例,因此默认的原型对象都会有一个指向Object.prototype的内部指针。所以这也是所有自定义类型都会继承toString() valueOf()等默认方法的根本原因。

你可能感兴趣的:(JavaScript)