JS继承多种方式

117 阅读2分钟

1.原型链继承

	function Super(name) {
		this.name = name;
	}
	Super.prototype.getSuperValue = function() {
		return this.name;
	}
    
	function Sub(age) {
		this.age = age;
	}
   	Sub.prototype.getSubValue = function() {
		return this.age;
	}
    
	Sub.prototype = new Super();
	let instance = new Sub();

这种方式有一个弊端 Sub.prototype(Super-instance)实例上的属性和方法被Sub的所有实例共享同一份数据 原型链示意图 原型图

2.盗用函数

	function Super(name) {
            this.name = name;
        }

        function Sub(...args) {
            Super.call(this, ...args);
        }

盗用函数解决了Sub实例共享Super实例数据问题,但是没有Super继承原型上的属性和方法

3.组合继承

	function Super(name) {
		this.name = name;
	}
    
    	function Sub(...args) {
    		Super.call(this, ...args);
	}
    
        const superInstance = new Super();
        superInstance.constructor = Sub;
        Sub.prototype = superInstance;
	这里要说的是实例属性上面是没有构造函数属性的,他拿的是原型对象上的构造函数,我们在设置构造函数原型对象属性的时候,要把原型对象的构造属性改成当前构造函数;
	上面通过原型链继承结合盗用构造函数,
    	1.解决了原型链继承Super实例(Sub.prototype)属性,方法共享的数据的问题
    	是通过盗用构造函数在Sub实例上对Super实例(Sub.prototype)属性,方法进行覆盖
        但是有一个问题Super函数调用两次.
        1. Super.call(this, ...age)
        2. new Super()

4.原型式继承

  function inhert(obj) {
      function F() {};
      F.prototype = obj;
      return new F();
  }

这类似于原生Object.create()的实现,他在作用在于不用声明类型,通过方法也能继承。使用场景是既可以拿到以前的数据,又可以覆盖之前的数据,不影响之前的对象数据。但跟原型链继承同一个通病,数据共享的问题。

5.寄生式继承

	function factory(obj) {
		const instance = inhert(obj);
        	instance.getSubValue = function() {
			console.log('sub');
		}
	}

寄生式继承不过是使用工厂函数在原型式继承上面增强罢了

6.寄生式组合继承

	function Super(name){
		this.name = name;
	}
    
        function Sub(name, age) {
            Super.call(this, name);
            this.age = age;
        }
    
      function merge(Sub, Super) {
          const superInstance = inhert(Super.prototype);
          superInstance.constructor = Sub;
          Sub.prototype = superInstance;
      }

这样就解决了两次Super调用的问题。

以上是ES5的继承

7.ES6 class继承

	class Super {
              constructor(name){
                  this.name = name;
              }
              getSuperValue(){
                  console.log('super')
              }
          }
    
        class Sub extends Super {
            constructor(name, age){
                super(name);
                this.age = age;
            }
            getSubValue() {
                console.log('sub');
            }
        }

简单又方便

上述继承方式源自于红宝书