Dean Front-end Dev Engineer

JS 的原型链继承

2018-02-17

原型链继承的作用

原型链继承,就是为了方便实例继承原型中的属性和方法,不重复写同样的代码。

原型链

要理解原型链的继承,首先要理解 构造函数、原型、实例 这三者之间的关系。

举个例子:

const Cat = function (name,age) {
    this.name = name;
    this.age = age;
};//构造函数
Cat.prototype.sayName = function () {
    console.log(this.name);
};//原型
const cat1 = new Cat('叮当',2);//实例
console.log(cat1 instanceof Cat);//true
cat1.sayName();//实例继承原型中的方法

简单来说,就是构造函数像是一个生产工厂,负责生产实例;

原型就是储存实例共同属性和方法的一个对象,这样就可以让方法,属性重复利用。

构造函数的 prototype 属性指向原型;

原型有一个 constructor 的属性指向构造函数;

实例中有一个 __proto__ 的属性指向原型。

__proto__ 的引用链被被作原型链。

原型链继承

const Cat = function (kind) {
    this.kind = kind;
};
Cat.prototype.sayAge = function () {
    console.log(this.age);
};
const Persian = function (name,color,age) {
    this.name = name;
    this.color = color;
    this.age = age;
}
Persian.prototype = new Cat('波斯猫');//让 Persian.prototype 属性指向 Cat 的实例,实现继承。
Persian.prototype.constructor = Persian;//将 constructor 重新指向对应的构造函数
const cat1 = new Persian('叮当','red',10);
cat1.sayAge();//10
console.log(cat1.kind);//波斯猫

有时候我们并不需要继承父类的属性,只需要它的方法。

Persian.prototype = new Cat();

这时候就会多出一个 kind 的属性。这时候我们可以这样

const Cat = function (kind) {
    this.kind = kind;
};
Cat.prototype.sayAge = function () {
    console.log(this.age);
};
const Persian = function (name,color,age) {
    this.name = name;
    this.color = color;
    this.age = age;
}
Persian.prototype = Object.create(Cat.prototype);//让 Persian.prototype 属性指向 Cat.prototype 新建的实例,实现继承。
Persian.prototype.constructor = Persian;//将 constructor 重新指向对应的构造函数
const cat1 = new Persian('叮当','red',10);
cat1.sayAge();//10
console.log(cat1.kind);//波斯猫
Object.getPrototypeOf(cat1) === Persian.prototype;

一个对象 obj,查找某一个属性或方法时,会先在自身查找,如果找到,就会输出。如果没有找到,就会继续在它的原型上找,如此类推,一直到 Object.prototype.__proto__ -> null


Comments

Content