类式继承
类式继承是将父类的实例赋值给子类的原型对象:
function Parent() { this.books = ['JS', 'PHP', 'CSS'] } Parent.prototype.fun = function () { console.log(1); }; function Child() { } Child.prototype = new Parent(); var instance1 = new Child(); var instance2 = new Child(); instance1.books.push('Node'); console.log(instance2.books); //["JS", "PHP", "CSS", "Node"] 如果你看过我上一节的内容,你就知道为什么了。 //直接告诉你原型吧: 因为books是instance1的原型对象的属性 上面是改变值 并没有赋值
所以这种类型的继承果断被pass掉。
构造函数继承
//构造函数继承一般讲公共属性先声明并且放在 构造函数内,当修改实例对象的name属性时就不会互相干扰了 function Human(name) { this.name = name; }function Male(name) { Human.call(this, name) } let person1 = new Male('arrayBuffer'); let person2 = new Male('jiaojiao');
实例化时,每个实例本身都会拥有构造函数中属性,所以修改这些属性时不会互相干扰。
组合模式
function Human(name, age) { this.name = name; this.age = age; } Human.prototype.fun = function () { console.log('sleeping'); }; function Male(name, age, weight) { this.weight = weight; Human.call(this, name, age) } Male.prototype = new Human(); //这里千万别不能 Human.prototype Male.prototype.goodAt = function () { console.log('搬砖') }; let man = new Male('arrayBuffer', 24, '60Kg'); console.log(man);
这里需要注意prototype的层级关系
组合模式能够解决上述两个问题,但是你看下图:
Male 的原型对象上多了age name属性这是什么鬼?这是因为执行 Male.prototype = new Human(),Male.prototype执向的对象就是这样的。即 new Human()执行了两次哟。