面向对象
一、类的声明与实例
类的声明两种方式
ES5
function Animal() {
this.name='name';
};
ES6
class Animal2 {
constructor(){
this.name='name';
}
}
实例化
new Animal(),
new Animal2()
二、类与继承
如何实现继承
继承的几种方式
1、构造函数部分继承,演示如下,缺点:父类原型对象上的say方法不能继承到子类上
function parent() {
this.name='parent';
}
parent.prototype.say=function () {
};
function child() {
修改父级this指向
parent.call(this);
this.type='child';
}
console.log(new child().say());
2、利用原型链,演示如下,缺点:由于原型链的原型对象是共用的,不同实例的原型对象是一样的,就会导致实例修改原型对象后,其他实例所引用的原型对象发生变化
function parent2() {
this.name='parent';
}
function child2() {
this.type='child';
}
// 原型链的核心
child2.prototype=new parent2();
console.log(new child2());
3、组合方式
组合1如下,优点分割了共用原型对象的影响,缺点父类实例生成2次,判断出实例是父类生成的(原因在于实例的constructor指向父类)
function parent2() {
this.name='parent';
this.play=[1,2,3];
}
function child2() {
parent2.call(this);
this.type='child';
}
child2.prototype=new parent2();
var s1=new child2();
var s2=new child2();
s1.play.push(4);
console.log(s1.play,s2.play);结果[1, 2, 3, 4] (3) [1, 2, 3]
console.log(s1.constructor===parent2);结果为true
console.log(s1.constructor===child2);结果为false
组合2如下,减少实例生成次数,但是判断的实例还是父类生成的
child2.prototype=parent2.prototype;
组合3,优点将父类和子类的原型对象隔开
function parent2() {
this.name='parent';
this.play=[1,2,3];
}
function child2() {
parent2.call(this);
this.type='child';
}
child2.prototype=Object.create(parent2.prototype);
child2.prototype.constructor=child2;
var s1=new child2();
var s2=new child2();
s1.play.push(4);
console.log(s1.play,s2.play);
console.log(s1.constructor===child2);结果为true