网站地图    收藏   

主页 > 前端 > javascript >

寄生组合式继承的优势详解

来源:未知    时间:2022-05-05 10:17 作者:xxadmin 阅读:

[导读] 在之前javascript面向对象系列的文章里面,我们已经探讨了组合继承和寄生继承,回顾下组合继承: functionPerson(uName){this.skills=[php,javascript];this.userName=uName;}Person.prototype.showUserName=functio...

在之前javascript面向对象系列的文章里面,我们已经探讨了组合继承和寄生继承,回顾下组合继承:

function Person( uName ){
      this.skills = [ 'php', 'javascript' ];
      this.userName = uName;
    }
    Person.prototype.showUserName = function(){
      return this.userName;
    }
    function Teacher ( uName ){
      Person.call( this, uName );
    }
    Teacher.prototype = new Person();

    var oT1 = new Teacher( 'ghostwu' );
    oT1.skills.push( 'linux' );
    var oT2 = new Teacher( 'ghostwu' );
    console.log( oT2.skills ); //php,javascript
    console.log( oT2.showUserName() ); //ghostwu

组合继承有个缺点,父类的构造函数会被调用两次.

第11行,设置子类原型对象(prototype),调用了第一次

第9行,实例化对象的时候,又调用一次

构造函数的目的是为了复制属性,第9行肯定是不能少的,第11行的目的是为了获取到父类原型对象(prototype)上的方法,基于这个目的,有没有别的方法

可以做到 在不需要实例化父类构造函数的情况下,也能得到父类原型对象上的方法呢? 当然可以,我们可以采用寄生式继承来得到父类原型对象上的方法

function Person( uName ){
      this.skills = [ 'php', 'javascript' ];
      this.userName = uName;
    }
    Person.prototype.showUserName = function(){
      return this.userName;
    }
    function Teacher ( uName ){
      Person.call( this, uName );
    }

    function object( o ){
      var G = function(){};
      G.prototype = o;
      return new G();
    }

    function inheritPrototype( subObj, superObj ){
      var proObj = object( superObj.prototype ); //复制父类superObj的原型对象
      proObj.constructor = subObj; //constructor指向子类构造函数,避免重写而失去constructor
      //为了解决组合式继承中构造函数被执行两次的问题,
//我们将指向父类实例改为指向父类原型, 减去一次构造函数的执行
      subObj.prototype = proObj; //再把这个对象给子类的原型对象
    }

    inheritPrototype( Teacher, Person );

    var oT1 = new Teacher( 'ghostwu' );
    oT1.skills.push( 'linux' );
    var oT2 = new Teacher( 'ghostwu' );
    console.log( oT2.skills ); //php,javascript
    console.log( oT2.showUserName() ); //ghostwu

其实,说白了寄生组合式继承就是一个借用构造函数 + 相当于浅拷贝父类的原型对象


其他方案:

寄生组合式继承, 即通过借用构造函数来继承属性, 在原型上添加共用的方法, 通过寄生式实现继承

			//寄生组合式继承, 即通过借用构造函数来继承属性, 在原型上添加共用的方法, 通过寄生式实现继承.
			// 上边的例子高效的体现了只调用了一次 SuperType 构造函数,并且因此也避免了在 SubType.prototype 上面创建不必要的 多余的属性.与此同时,原型链还能保持不变
			// function inheritPrototype(subType, superType) {
			// 	var prototype = Object.create(superType.prototype); // 创建对象,创建父类原型的一个副本
			// 	prototype.constructor = subType; // 增强对象,弥补因重写原型而失去的默认的constructor 属性
			// 	subType.prototype = prototype; // 指定对象,将新创建的对象赋值给子类的原型
			// }
 
 
			// 父类初始化实例属性和原型的属性和方法
			function SuperType(name) {
				this.name = name;
				this.colors = ["red", "blue", "green"];
				this.sheet = function(sheet) {
					console.log(this.name + '正在sheet!' + sheet);
				}
			}
			SuperType.prototype.sayName = function() {
				console.log(this.name);
			};
 
			// 借用构造函数继承构造函数的实例的属性(解决引用类型共享的问题)
			function SubType(name, age) {
				SuperType.call(this, name);
				this.age = age;
			}
 
			(function(SubType, SuperType) {
				var prototype = Object.create(SuperType.prototype) //创建父类原型的一个副本
				prototype.constructor = prototype // 增强对象,弥补因重写原型而失去的默认的constructor 属性
				SubType.prototype = prototype //指定对象,讲新创建的对象赋值给子类的原型
			}(SubType, SuperType))
			// 将子类型的原型重写替换成父类的原型
			
			// inheritPrototype(SubType, SuperType);
 
			// 对子类添加自己的方法
			SubType.prototype.sayAge = function() {
				console.log(this.age);
			};
 
			var instance1 = new SubType("heyushuo", 12);
			var instance2 = new SubType("kebi");
			console.log('instance1', instance1)
			console.log('instance2', instance2)
			instance1.sayName(); //heyushuo
			instance1.sayAge(); //12
			instance2.sayName(); //kebi
 
			instance1.colors.push("yellow"); // ["red", "blue", "green", "yellow"]
			instance1.colors.push("black"); // ["red", "blue", "green", "black"]



以上这篇[js高手之路]寄生组合式继承的优势详解就是小编分享给大家的全部内容了

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论