Javascript面对对象. 第五篇

继承

继承是面向对象中一个核心的概念。其他正统面向对象语言都会用两种方式实现继承:

一个是接口实现,一个是继承

而ECMAScript只支持继承,不支持接口实现,而实现继承的方式依靠原型链完成。

//继承,通过原型链实现
	function Box(){  //被继承的函数叫超类型(父类,基类)
    		this.name="link"
    	}
   	function Dest(){//继承的函数叫子类型(子类,派生类)
    		this.age=25;
    }
    	function Table(){
   		this.level="dfsfsdf";
    }
   	//通过原型链继承,超类型实例化后的对象实例,赋值给予类型的原型属性
    	//new Box()会将Box构造里的信息和原型里的信息都提交给Dest
    	Dest.prototype=new Box();
    	Table.prototype=new Dest();
		var dest=new Dest();
   	alert(dest.age)
   	alert(dest.name)
   	
   	var table=new Dest();
   	alert(table.age)
   	alert(table.name)

 如果要实例化Dest,那么Box实例中的name="link",原型中添加相同的属性name="xiao",如果有Box有就是link,没有就是xiao

//继承,通过原型链实现
      	function Box(){  //被继承的函数叫超类型(父类,基类)
      		//this.name="link"
      	}
      	Box.prototype.name="xiao";
      	function Dest(){//继承的函数叫子类型(子类,派生类)
      		this.age=25;
      }
      	
    
      	//通过原型链继承,超类型实例化后的对象实例,赋值给予类型的原型属性
      	//new Box()会将Box构造里的信息和原型里的信息都提交给Dest
      	Dest.prototype=new Box();
      		var dest=new Dest();
      	alert(dest.age)
      	alert(dest.name)  //xiao

  ps:以上原型链继承还少一环,那就是Object,所有的构造函数都继承自Object。而继承object是自动完成的,并不需要程序员手动继承。

//经过继承后的实例,他们的从属关系会是什么?
			alert(table instanceof Object);   //true
			alert(dest instanceof Table);      //false,dest是Table的超类
			alert(table instanceof Dest);    //true
			alert(table instanceof Box);     //true

 在javascript里,被继承的函数称为超类型(父类,基类),继承的函数称为子类型(子类,派生类)。继承也有之前的问题比如字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数。  

为了解决共享和超类型无法传参的问题,我们采用了一种叫借用构造函数的技术,或者成为对象冒充(伪造对象,经典继承)的技术来解决这两种问题。             

	//使用对象冒充
		function Box(name,age){
			this.name=name;
			this.age=age; 
			this.family=['哥哥','妹妹','弟弟']  //引用类型,放在构造里就不会共享。
		}
		//Box.prototype.family='姐姐';
		
		function Dest(name,age){   
			Box.call(this,name,age)   //对象冒充,对象冒充只能继承构造里的信息
		}
		var dest=new Dest('link',111);
		dest.family.push('姐姐');
		alert(dest.name);
		alert(dest.family);
		
		var dest2=new Dest('html',111);
		alert(dest2.family);

借用构造函数虽然解决了刚才两种问题,但是没有原型,复用则无从谈起。所以,我们需要原型链+借用构造函数的模式,这种模式成为组合继承

    function Box(name,age){
			this.name=name;
			this.age=age; 
			this.family=['哥哥','妹妹','弟弟']  //引用类型,放在构造里就不会共享。
		}
		Box.prototype.run=function(){
			return this.name+this.age+"运行中...";
		}
		//构造函数里的方法,放在构造里,每次实例化,都会分配一个内存地址,浪费,所以最好放到原型里,保证多次实例化只有一个地址。
		function Dest(name,age){   
			Box.call(this,name,age)   //对象冒充,对象冒充只能继承构造里的信息
		}
		
		Dest.prototype=new Box();   //原型链继承
		
		var dest=new Dest('link',111);
		alert(dest.run());

 还有一种继承模式叫:原型式继承:这种继承借助原型并基于已有的对象创建对象,同时还不必因此创建自定义类型。

我们学习过:
1.原型链继承,2.借用构造函数继承(对象冒充继承)3.组合继承(结合前俩种)

4.原型式继承

//4.原型式继承
		
		//临时中转函数
		function obj(o){    //o表示将要传递进入的一个对象			
			function F(){}   //F构造是一个临时新建的对象,用来存储传递过来的对象
			F.prototype=o;   //将o对象实例赋值给F构造的原型对象
			return new F(); //最后返回这个得到传递过来对象的对象实例
		}
		
		//F.prototype=o 其实就是相当于Dest.prototype=new Box();
		
		//这个字面量的声明方式,相当于var box=new Box();
		var box={
			name:'link',
			age:23,
			family:['哥哥','妹妹','弟弟'] 
		}
		//box1等于new F();
		var box1=obj(box);
		alert(box1.name);
		alert(box1.family);
		box.family.push('姐姐');
		alert(box1.family);
		
		
		var box2=obj(box);
		alert(box2.family);

 5.寄生式继承=原型式+工厂模式

//临时中转函数
		function obj(o){
		   function F(){}
		   F.prototype=o;
		   return new F();
		}
		//寄生函数
		function  create(o){
			var f=obj(o);
			return f;
		}
		var box={
			name:'link',
			age:23,
			family:['哥哥','妹妹','弟弟'] 
		}
		
		var box1=new create(box);
		alert(box1.name);
//临时中转函数
		function obj(o){
		   function F(){}
		   F.prototype=o;
		   return new F();
		}
		//寄生函数
		function  create(box,dest){
			var f=obj(box.prototype);
			f.constructor=dest;   //指向了Dest,没有是话指向Box
			dest.prototype=f;
			
		}
		function Box(name,age){
			this.name=name;
			this.age=age;
		}
		Box.prototype.run=function(){
			return this.name+this.age+"运行中。。。";
		}
		function Dest(name,age){
			Box.call(this,name,age)
		}
		//通过寄生组合继承来实现继承
		create(Box,Dest);   //这句话用来替代Dest.prototype=new Box();
		
		var dest=new Dest('link',23);
		alert(dest.run());
		alert(dest.constructor);   
原文地址:https://www.cnblogs.com/linkhtml/p/5684568.html