类与实例
创建类
//es6
class Animal1 {
constructor () {
this.name = name
}
}
//es5
function Animal2 (name) {
this.name = name
}
实例化
let new1 = new Animal1()
let new2 = new Animal2()
类与继承
实现继承的几种方式
- 方式一:利用构造函数进行继承
function Parent1 () {
this.name = '父'
}
function child1 () {
Parent1.call(this) //重点 将父级构造的this指向指到子类的实例上去,父类的属性子类也会有
this.type = 'child'
}
console.log(new child1)
但是这种方法缺点是无法继承父类的原型链上的属性
- 方式二: 利用原型链进行继承
function Parent2 () {
this.name = 'parent2'
this.arr = [1, 2, 3]
}
function child2 () {
this.type = 'child2'
}
child2.prototype = new Parent2()
console.log(new child2)
let s1 = new child2()
let s2 = new child2()
s1.arr.push(4)
console.log(s1.arr, s2.arr) //输出都是 [1, 2, 3, 4]
这样能继承原型链上的属性,但是如果改变父类的元素,所有的子类属性也会进行更改,因为这相当于改变了原型对象
- 方式三: 组合方法,同时使用构造函数跟原型链
function parent3 () {
this.name = 'parent3'
this.arr = [1, 2 ,3]
}
function child3 () {
parent3.call(this) //执行一次父类
this.type = 'child3'
}
child3.prototype = new parent3() // 再次执行父类
let s3 = new child3()
let s4 = new child3()
s3.arr.push(4)
console.log(s3, s4) // [1,2,3,4] [1,2,3]
但是这种方法也不是完美的,这种方法还有个弊端就是父类被执行了两次
- 方式三 优化1
function parent4 () {
this.name = 'parent4'
this.arr = [1, 2 ,3]
}
function child4 () {
parent3.call(this)
this.type = 'child4'
}
child4.prototype = parent4.prototype
这样就避免了父类被执行两次,但是这还不算完美的,因为这样无法去区分实例是父类还是子类直接创建的
- 最终完美优化版
function parent5 () {
this.name = 'parent5'
this.arr = [1, 2 ,3]
}
function child5 () {
parent3.call(this)
this.type = 'child5'
}
// Object.create创建一个中间对象,引用父类的原型对象,这样用于隔离子类的原型对象跟父类的原型对象直接关联
child5.prototype = Object.create(parent5.prototype)
//为子类添加一个构造函数
child5.prototype.constructor = child5
console.log(child5.prototype.constructor === parent5.prototype.constructor)
//输出false
网友评论