将父类的实例作为子类的原型
- function Father(){
- this.name = 'Tony'
- }
-
- function Son() {}
-
- Son.prototype = new Father()
-
- let son = new Son();
-
- console.log(son.name) // Tony
缺点:
在子类构造函数中调用父类构造函数并通过call或apply给父类传参、修改this指向。
- function Father(name){
- this.info = {
- name:name,
- job:'teacher'
- }
- this.sayName(){
- console.log(this.info.name)
- }
- }
-
- function Son (name){
- Father.call(this,name)
- }
-
- let s = new Son('Jerry');
-
-
- let s2 = new Son ('Mike');
-
-
- console.log(s.info.name) //Jerry
-
- console.log(s2.info.name) // Mike
通过使用call()
或apply()
方法,Parent
构造函数在为Child
的实例创建的新对象的上下文执行了,就相当于新的Child
实例对象上运行了Parent()
函数中的所有初始化代码,结果就是每个实例都有自己的info
属性。
优点:
缺点:
组合式继承综合了原型链继承和构造方法继承的优点,通过原型链继承获得父类原型对象上的属性和方法。通过引用父类构造方法达到隔离子类共享属性,给父类传递参数 。
- function Father (name) {
- this.name=name
-
- }
-
- Father.prototype.sayName=function(){
- console.log(this.name)
- }
-
-
- function Son (name) {
- Father.call(this,name)
- }
- Son.prototype = new Father()
- //手动挂载构造起,指向自己的构造方法
- Son.prototype.constructor = Son
-
- let s1 = new Son('Mike')
-
- s1.sayName() // Mike
-
- let s2 = new Son('Jerry')
-
- s2.sayName() //Jerry
优点:
对参数对象的一种浅复制 ,当Object.create()只有一个参数时与下面代码中的Object()方法相同
- let student = {
- hobbies:['music','football','basketball']
- }
-
- function Object (o) {
- function F(){}
- F.prototype=o
- return new F()
- }
-
- let s1 = Object(student)
- s1.hobbies.push('sing')
-
- console.log(s1.hobbies) //['music', 'football', 'basketball', 'sing']
- let s2 = Object(student)
- s2.hobbies.push('dance')
- console.log(s2.hobbies) //['music', 'football', 'basketball', 'sing','dance']
优点:
缺点:
寄生式继承是在原型继承基础上的拓展,类似于一个工厂模式,即创建一个用于封装继承的函数,该函数内部对参数对象做了增强。
- function Object (person){
- function F () {}
- F.prototype = person;
- return new F()
- }
-
-
- function createObject(person){
-
- let obj = Object(person)
- obj.sayHello = function(){
- console.log('hello')
- }
-
- return obj
- }
-
- let person = {
- name:'tony',
- age:32
- }
-
- let p1 = createObject(person)
-
- p1.sayHello() //hello
-
- p1.name //tony
组合式继承有看似完美却有一个缺点,那就是父类的构造函数会被执行两次,一次是父类实例化时,一类是子类实例化时。这样就会造成内存没必要的消耗,寄生式组合继承正是弥补了这个短板,时目前最为理想的继承方式。
- function extend(subClass,superClass){
- var prototype = object(superClass.prototype);//创建对象
- prototype.constructor = subClass;//增强对象
- subClass.prototype = prototype;//指定对象
- }
-
- class supClass {
-
- constructor(name) {
- this.name = name
- }
- sayName(){
- console.log(this.name)
- }
- }
-
- class subClass extends supClass{
-
-
- constructor (name) {
- super(name)
- this.name = name
- }
- }
-
-
- let sub = new subClass ('subClass')
-
- console.log(sub.name)
-
- sub.sayName() // subClass