1.什么是继承?
我理解的继承就是子类继承父类的行为和特征,使得子类对象具有父类的属性和方法。
2.如何实现继承?
- 1.通过原型链的方式实现继承
function Person(name) {
this.name = name
this.colors = ['red', 'blue']
}
Person.perototype.sayhi = function () {
console.log('hi')
}
function Man (age) {
this.age = age
this.gender = '男'
}
Man.prototype = new Person()
//此时Man的实例对象的原型链是 Man的实例对象 => Man.prototype(Person的实例对象)
//=> Person.prototype => Object.prototype
//根据原型链可以实现Man使用Person的方法和属性
const p1 = new Man(20)
p1.colors.push('green')
const p2 = new Man(21)
console.log(p1.colors)
console.log(p2.colors)
p.sayhi()
- 通过原型链的方式的优点和缺点: 优点: 通过原型链的方式可以实现父类方法和属性的继承,并且可以通过instanceof来确定继承的父类 缺点: 不能通过向父类进行传参、 如果父类属性中有引用值(如数组),会在子类的所有实例对象中共享,因此其中一个改变父类中的引用值,那么会导致在所有的子类实例对象中都改变
- 2.通过构造函数的方式实现继承
function Animal(name) {
this.name = name
this.colors = ['red', 'blue']
this.sayhi = function () {
console.log('hi')
}
}
function Dog(name,age, gender) {
Animal.call(this, name)
this.age = age
this.gender =gender
}
const dog = new Dog('小黑', 3, '男')
console.log(dog.name)
dog.sayhi() //通过构造函数的方式不会改变原型链, Dog的原型链还是Dog的实例对象 =>
// Dog.prototype => Object.prototype 因此子类不能调用父类构造函数原型上的方法
- 通过构造函数的方式的优点和缺点: 优点: 通过构造函数的方式实现继承,可以向父类进行传参。构造函数的方式父类属性中有引用值,不会造成会在所有的实例对象中共享。 缺点: 需要两次调用父类构造函数,效率浪费。必须在父类构造函数中定义方法,因此函数不能重用。子类不能调用父类构造函数原型上的方法。
- 3.通过组合继承的方式实现继承(通过构造函数实现属性的继承,通过原型链的方式实现继承原型上的属性和方法)
function Person (name) {
this.name = name
this.colors = ['red', 'blue']
}
Person.prototype.sayhi = function (){
console.log('hi')
}
function Man (name, age, gender) {
Person.call(this, name)
this.age = age
this.gender = gender
}
Man.prototype = new Person
const p1 = new Man('张三', 20, '男')
p1.colors.push('green')
const p2 = new Man('李四', 18, '男')
console.log(p1.colors)
console.log(p2.colors)
//此时原型链是 Man的实例对象 => Man.prototype(Person的实例对象) =>Person.prototype => Object.prototype
通过组合继承的方式的优点和缺点: 优点: 解决了原型链继承和原型链继承的缺点 缺点: 仍然是会调用两次父类构造函数
- 4.通过原型式继承的方式实现继承
function create(o) {
function F (){}
F.prototype = o
return new F()
}
//此方法的作用就是传递一个对象进去,返回一个临时类型的实例 本质上:create对传入的对象进行了一次浅复制
const object = {
name = '张三'
colors = ['red', 'blue']
}
const p = create(object)
console.log(p)
//此时的原型链为:p => F.prototype => Object.prototype
通过原型式继承的方式的优点和缺点: 优点: 不需要单独创建构造函数 缺点: 和原型链继承的方式一样,所有的实例对象仍然会共享信息
- 5.通过寄生式继承
function create(o) {
function F (){}
F.prototype = o
return new F()
}
function createAnother(object) {
const clone = create(object)// 通过调用函数创建一个对象
clone.sayhi = function () {//增强这个对象
console.log('hi')
}
return clone
}
const Person = {
name: '张三',
colors: ['blue', 'red']
}
const anotherPerson = createAnother(Person)
anotherPerson.sayhi()
//此时的原型链为: anotherPerson => F.prototype => Object.prototype
通过寄生式继承的优点和缺点: 优点: 可以自己定义方法 缺点: 引用值仍然会在所有的实例对象中共享信息,而且给对象添加函数会导致函数难以重用。
- 6.通过寄生组合式继承
function Person(name) {
this.name = name
this.colors = ['red', 'blue']
}
Person.prototype.sayhi = function () {
console.log('hi')
}
function Man (name, age, gender) {
Person.call(this, name)
this.age = age
this.gender = gender
}
function inheritPrototype (Man, Person) {
const o = create(Person.prototype) //创建一个对象
o.constructor = Man
Man.prototype = o
}
inheritPrototype(Man, Person)
//此时原型链是: Man的实例对象 => Man.prototype => Person.prototype => Object.prototype
通过寄生式组合继承是引用类型继承的最好方式
3.ES6中实现继承的方式
使用extends关键字,就可以继承任何拥有[[construct]]和原型的对象
派生类的方法可以通过super关键字引用它们的原型。
关于ES6中的类以及ES6中继承的具体内容会在后面的文章中发布
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!