1.类与实例
类的声明
/**
* 类的声明,采用构造函数声明
*/
var Animal = function () {
this.name = 'Animal';
};
/**
* es6中class的声明
*/
class Animal2 {
constructor () {
this.name = 'Animal2';
}
}
生成实例
/**
* 实例化
*/
console.log(new Animal(), new Animal2());
2.类与继承
继承的几种方式
- 1.借助构造函数实现继承
实现了部分继承,只能继承父类构造函数体内的属性;父类的原型对象上的方法不能继承。
/**
* 借助构造函数实现继承
*/
function Parent1 () {
this.name = 'parent1';
}
Parent1.prototype.say = function () {
//Parent1 原型链上的方法并没有被 Child1 所继承
};
function Child1 () {
Parent1.call(this);//apply;改变函数运行的上下文(将父级的构造函数this指向子构造函数的实例上)
this.type = 'child1';
}
console.log(new Child1(), new Child1().say());//Uncaught TypeError: (intermediate value).say is not a function
- 2.借助原型链实现继承
弥补了构造函数继承的不足,但是继承后原型链上的原型对象是共用的,改变一个其余的也都跟着改变。
/**
* 借助原型链实现继承
*/
function Parent2 () {
this.name = 'parent2';
this.play = [1, 2, 3];
}
function Child2 () {
this.type = 'child2';
}
Child2.prototype = new Parent2();//new Child2().__proto__===Child2.prototype
var s1 = new Child2();
var s2 = new Child2();
console.log(s1.play, s2.play);//(3) [1, 2, 3] (3) [1, 2, 3]
s1.play.push(4);
console.log(s1.play, s2.play);//(4) [1, 2, 3, 4] (4) [1, 2, 3, 4]
- 3.组合方式
实现向对象继承的通用方式。(缺点:在实例化1个子类的时候,父类的构造函数执行了2次)
/**
* 组合方式
*/
function Parent3 () {
this.name = 'parent3';
this.play = [1, 2, 3];
}
function Child3 () {
Parent3.call(this);//在子构造函数中执行父级构造函数
this.type = 'child3';
}
Child3.prototype = new Parent3();
var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4);
console.log(s3.play, s4.play);//(4) [1, 2, 3, 4] (3) [1, 2, 3]
- 4.组合方式的优化1
优点:实例化1个子类的时候,父类的构造函数执行了1次;
不足:无法区分一个对象是 直接 由子类实例化的还是通过父类实例化的。
/**
* 组合继承的优化1
* @type {String}
*/
function Parent4 () {
this.name = 'parent4';
this.play = [1, 2, 3];
}
function Child4 () {
Parent4.call(this);
this.type = 'child4';
}
Child4.prototype = Parent4.prototype;//实例化1个子类的时候,父类的构造函数执行了1次
var s5 = new Child4();
var s6 = new Child4();
console.log(s5, s6);//Child4 {name: "parent4", play: Array(3), type: "child4"} Child4 {name: "parent4", play: Array(3), type: "child4"}
console.log(s5 instanceof Child4, s5 instanceof Parent4);//true true
console.log(s5.constructor);
/**
ƒ Parent4() {
this.name = 'parent4';
this.play = [1, 2, 3];
}
*/
- 5.组合方式的优化2
完美写法。通过 Object.create()
创建一个中间对象,再修改子类实例的构造函数。
/**
* 组合继承的优化2
*/
function Parent5 () {
this.name = 'parent5';
this.play = [1, 2, 3];
}
function Child5 () {
Parent5.call(this);
this.type = 'child5';
}
Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor=Child5;
var s7=new Child5();
console.log(s7 instanceof Child5,s7 instanceof Parent5);//true true
s7.constructor
/**
ƒ Child5() {
Parent5.call(this);
this.type = 'child5';
}
*/