什么是继承
用官方点的话讲继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,同时还可以在子类中重新定义以及追加属性和方法。通俗的来说继承就是子类可以
什么是继承
用官方点的话讲继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,同时还可以在子类中重新定义以及追加属性和方法。通俗的来说继承就是子类可以从父类那里复用一些属性和方法,从而达到复用代码的一个效果。
实现继承的6种方式
- 原型链继承
- 构造函数继承
- 组合继承(伪经典继承)
- 原型式继承
- 寄生式继承
- 寄生组合式继承
- class 类继承
1. 原型链继承
function Person() { this.name = 'bruce' this.age = 18 this.gender = '男' this.like = { sport: 'running', book: 'JavaScript' } this.getName = function() { console.log(this.name); } } function Student() { this.school = '新华小学' } let s = new Student() console.log(s.name); // 未继承前 undefined Student.prototype = new Person() // 继承之后 let s1 = new Student() s1.getName() // bruce console.log(s1.like.book); // JavaScript s1.like.book = 'Java' // 修改引用类型的值 s1.name = 'jack' // 修改非引用类型的值 console.log(s1.like.book); // Java s1.getName() // jack console.log('----------'); let s2 = new Student() s2.getName() // bruce console.log(s2.like.book); // Java
所谓的原型链继承,在我的理解就是子类通过原型链来继承到父类的属性,在上面的代码中我们也可以看到在子类实例s
没有继承到父类的属性时,子类去访问父类才有的属性值为:undefined
。
在将父类实例对象挂载到子类Student构造函数的原型上面后,那么此时子类的原型上面就有了父类的全部属性。因为Person
的实例对象被显示的挂载到了Student
的原型上面。所以子类在继承之后,所有实例化的子类都拥有了跟父类一样的属性,于是这样子类就通过原型链实现了继承。
优点: 子类可以继承到父类的方法。
缺点:
- 会在子类实例上共享父类所有的引用类型数据,也就是子类的原型被父类属性覆盖。
- 子类实例不能给父类构造函数传参。
function Person(t) { this.property = t } function Student(t) { this.typeproperty = t } Student.prototype = new Person() let s=new Student('a') console.log(s.property) // undefined console.log(s.typeproperty) // a
这样子类实例传的参数就不能给到父类构造函数里面了。
2. 构造函数继承
function Person(name,age) { this.name = name this.age = age this.like = { sport: 'running', book: 'JavaScript' } this.getName = function () { console.log(this.name); } } Person.prototype.sayHello = function () { console.log('你好'); } function Student(name, age,) { Person.call(this, name, age) // 借用构造函数 } let s1 = new Student('bruce',18) s1.getName() // bruce s1.name='jack' s1.getName() // jack s1.like.sport='swimming' console.log(s1.like.sport); // swimming console.log('------'); let s2=new Student('lucy',19) s2.getName() // lucy console.log(s2.like.sport); // running
构造函数继承就是使用强制改变 this 指向,借用一个构造函数继承。相较于原型链继承,构造函数继承不会共享父类上的引用类型数据,不会互相影响。
缺点:1.不能访问到父类原型属性上面的方法和参数,即 Person.prototype
上的都不能访问到。
Person.prototype.sayHello = function () { // 在 Person 的原型上面加一个方法 console.log('你好'); } let s1 = new Student('bruce',18) s1.sayHello() // s1.sayHello is not a function
3. 组合继承(伪经典继承)
相较于原型链继承,构造函数继承好像已经非常完美了,但是它还是存在着一个最大的缺点就是:不能继承到父类的原型上面的属性。但是原型链继承就好像没有这个问题,如果将这两个继承方式组合起来搭配使用