3-22 原型链继承
核心:实例化父类函数之后,将其拷贝到子类的原型prototype上。继承父类之后,子类可以使用父类的实例属性以及父类的原型属性
优点:从已有的对象衍生新的对象,不需要创建自定义类型
缺点1,新实例向父类构造函数传参,不符合面向对象编程的规则
function Person(name, age, job) {
this.name = name;
this.age = age;
this.ob = job;
}
function Man(age) {
this.name = age;
}
var m = new Man('Anthony', 27, 'PE');
m.prototype = new Person('thony', 27, 'PE');
var v = new Man('maker', 32, 'TW');
v.prototype = new Person('Alice', 21, 'VN');
console.dir(m);
console.dir(v);
新实例无法向父类构造函数传参;(并不是语法上不能实现对构造函数的参数传递,而是这样做不符合面向对象编程的规则:
对象(实例)才是属性的拥有者。如果在子类定义时就将属性赋了值,就变成了类拥有属性,而不是对象拥有属性了。)
缺点2,原型引用属性会被所有实例所共享,一改全改,后果严重
function Person() {
this.books = ["javascript", "css", "html"];
}
function Man(books) {
this.books = this.__proto__.books;
}
const p = new Person();
var instance1 = new Man();
instance1.prototype = p
var instance2 = new Man();
instance2.prototype = p
instance1.prototype.books.push('设计模式')
// console.log(instance1.prototype.books) // javascript', 'css', 'html', '设计模式
// console.log(instance2.prototype.books); // javascript', 'css', 'html', '设计模式
原型引用属性会被所有实例所共享,因为是整个父类对象充当子类的原型对象,所以这个缺陷无法避免
(由于子类通过其原型prototype对父类实例化,继承了父类,所以说父类的共有属性如果是引用类型,
就会在子类中被所有实例共用,因此一个子类的实例更改了子类原型从父类构造函数中继承来的属性就会直接影响到其他子类