类的声明
1. 通过构造函数声明
function Animal() {
// this表明这是一个构造函数
this.name = name;
}
2. es6声明
class Animal2 {
constructor() {
this.name = name;
}
}
将类实例化成对象:通过new就可以实例化一个类
console.log(new Animal, new Animal2)
类的继承(本质就是原型链)
1. 通过构造函数实现继承
function Parent1() {
this.name = 'parent1'
}
Parent1.prototype.say = function () {
console.log('parent1 原型链')
}
function Child1() {
// call\apply 改变函数运行的上下文
// 将父级构造函数的this指向子构造函数的实例上去
// 导致父级的构造函数里的内容子类里面也有
Parent1.call(this)
this.type = 'child1'
}
console.log(new Child1)
缺点:父类原型链上面的东西并没有被子类所继承
2. 借助原型链实现继承
function Parent2() {
this.name = 'parent2'
this.play = [1, 2, 3];
}
function Child2() {
this.type = 'child2'
}
// prototype属性是为了让这个构造函数的实例能访问到他的原型对象上
Child2.prototype = new Parent2();
// Parent2.prototype.say = function(){
// console.log('parent2 原型链')
// }
console.log(new Child2().__proto__)
let s1 = new Child2()
let s2 = new Child2()
console.log(s1.play, s2.play)
s1.play.push(4)
缺点:原型链中的原型对象是共用的
所以改其中一个原型对象的时候其实就是改另一个的原型对象
3. 组合方式
function Parent3() {
this.name = 'parent3'
this.play = [1, 2, 3];
}
function Child3() {
Parent3.call(this)
this.type = 'child3'
}
Child3.prototype = new Parent3();
Parent3.prototype.say = function () {
console.log('parent3 原型链')
}
let s3 = new Child3()
let s4 = new Child3()
s3.play.push(4)
console.log(s3.play, s4.play)
缺点:父级构造函数执行了两次(没有必要)
4. 组合优化方式1
function Parent4() {
this.name = 'parent4'
this.play = [1, 2, 3];
}
function Child4() {
Parent4.call(this)
this.type = 'child4'
}
Child4.prototype = Parent4.prototype;
let s5 = new Child4()
let s6 = new Child4()
s5.play.push(4)
console.log(s5.play, s6.play)
console.log(s5 instanceof Child4, s5 instanceof Parent4)
// 如何判断一个是直接由他的子类实例化的还是他的父类实例化的
console.log(s5.constructor)
5. 组合优化方式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) // __proto__
Chil5.prototype.constructor = Chil5;
let s7 = new Child5()
console.log(s7 instanceof Chil5, s7 instanceof Parent5)
// 如何判断一个是直接由他的子类实例化的还是他的父类实例化的
console.log(s7.constructor)