JS 继承的介绍与实现

继承的介绍

JS 是一种面向对象的 弱类型的 解释性的语言
弱类型 声明变量的时候不需要注明数据类型

 int a =1;   
 float//(强类型) 
 var a=1.2;

解释性 解释一句执行一句 编译性 一次性全部翻译完 然后再执行

面向对象 封装 继承 多态 (js语言没有多态)
封装 将一个功能都放在一个对象里面 只需要向外界暴露一个接口 需要使用的时候 直接调接口就可以了并不需要管底层是怎么实现的

push //向数组的最后添加一个元素
			var arr=[12,23];
			arr.push(15);

继承:是指js对象之间的继承 如果我们想让一个对象拥有另一个对象的属性或者方法 那么就可以让这个对象继承另一个对象

实现继承的方式

1.实现构造函数来实现继承
实现方式:使用call等方法 是一个对象的this指向另一个对象 从而让其拥有这个对象的属性和方法
缺点:无法继承父类原型上面的方法 对于子类不需要的方法 每次创建都会拥有 浪费内存空间
有很多构造函数的情况下,如果需要给所有的构造函数添加属性 ,那么就需要分别去加 就不便于维护

function Perent(name,age){
		this.name=name;
		this.age=age;
		this.work=function(){
			console.log("我要赚钱");
		}
	}
	
	Perent.prototype.test=function(){
		console.log(111);
	}
	Perent.prototype.type="人类";
	
	var p1=new Perent("父亲",36);
	
	// function Child(name,age,gender){
	// 	this.name=name;
	// 	this.age=age;
	// }
	// var c1=new Child("孩子",12);
	
	// call apply bind 修改this指向

	function Child(name,age){
			Perent.call(this,name,age)
		}
		var c2=new Child("amy",12);
		console.log(c2);
		
		//c2.test();  //报错
		c2.work() //执行了函数体

就是说只是把父亲构造函数里面的属性和方法继承了 但是父类原型里面的方法继承不了
创建的child对象并不需要work方法 但每次创建都会有 浪费空间

2.原型拷贝继承(混入式继承)
实现方式:使用for-in遍历父类原型里面的所有属性 依次加入子类的原型中
缺点:原型中子类不需要的方法或者属性也继承过来了 占用内存空间

	function Perent(name,age){
  	this.name=name;
  	this.age=age;
  	this.work=function(){
  		console.log("我要赚钱");
  	}
  }
  
  Perent.prototype.test=function(){
  	console.log(111);
  }
  Perent.prototype.type="人类";
  
  
  function Child(name,age){
	  this.name=name;
	  this.age=age;
  }
  
  
  //原型对象拷贝
  for(var key in Perent.prototype){
	  Child.prototype[key]=Perent.prototype[key];
	  console.log(Perent.prototype[key]);
  }
  var c1=new Child("张三",12);
  c1.test();
  console.log(c1.type);

3.原型链继承
实现方法:利用原型链来实现继承 父类的一个实例化对象作为子类的原型
缺点:子类实例和父类实例的原型对象上有成员的共享问题

		function Perent(name,age){
			this.name=name;
			this.age=age;
			this.work=function(){
				console.log("我要赚钱");
			}
		}
		
		Perent.prototype.test=function(){
			console.log(111);
		}
		Perent.prototype.type="人类";
		
		
		function Child(name,age){
				  this.name=name;
				  this.age=age;
		}
		
		
		Child.prototype=new Perent();
		
		console.log(Child.prototype.constructor);
		//重新替换原型之后 构造函数并不指向原构造函数 所以要将构造函数指向原函数
		Child.prototype.constructor=Child;
		Child.prototype=new Perent();
		
		var c1=new Child("张三",12);
		console.log(c1.type);
		c1.test();

为什么不直接使用Child.prototype=Perent?
把父类的构造函数直接替换掉子类的原型会导致 父类构造函数的私有属性发生变化
甚至有些成员 父类构造函数并不需要

Child.prototype=Perent;
		Child.prototype.study=function(){
			console.log("good good study");
		}
		console.dir(Perent);
		Perent.study();

4.组合继承(原型链 和call继承组合)

function Father(){
			this.name=name;
			this.run=function(){
				console.log(this.name+"我要跑步");
			}
		}
		
		Father.prototype={
			constructor:Father,
			type:"人类",
			eat:function(){
				console.log(this.name+"我要吃饭");
			}
		}
		
		function Son(age){
			//这个是继承父类构造函数里面的属性或者方法
			Father.call(this);
			this.age=age;
			this.study=function(){
				console.log(this.name+"我要开始学习了");
			}
		}
		
		
		//继承父类原型中的成员
		Son.prototype=new Father();
		
		Son.prototype.constructor=Son;
		
		Son.prototype.sleep=function(){
			console.log(this.name+"我要睡觉了");
		}
		
		var s1=new Son(12);
		//这个是父类构造函数里面的方法
		s1.run();
		
		//是父类原型里面的方法
		s1.eat();
		console.log(s1.type);
		
		//自己构造函数里面的方法
		s1.study();
		
		//自己的原型里面的方法
		s1.sleep();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值