继承的五种方法

继承是指在原型对象的所有属性和方法,都能被实例对象共享。也就是说,我们只要在原有对象的基础上,略作修改,得到一个新的的对象。

实现对象 继承的5种方式

1.原型链继承

 JavaScript使用原型链作为实现继承的主要方法,实现的本质是重写原型对象

function Fn(name){
					this.name = name;
				}
				Fn.prototype.say = function(){
					console.log('我是'+this.name)
				}
				Fn.prototype.car = function(){
					console.log('我有一辆小汽车')
				}
				
				function Son(name){
					this.name = name;
					
				}
				Son.prototype = Fn.prototype;   //将Fn原型对象 赋值 给Son             ****
				// Son.prototype = new Fn('父亲')     //将new出来的实例对象赋值给Son   不推荐
				Son.prototype.constructor = Son;  //改变Son原型对象中的指向   指向自己
				
				var f = new Fn('父亲');
				console.log(f)
				// f.say();
				// f.car();
				
				var s = new Son('儿子') 
				s.__proto__.car = function(){   //儿子 修改方法  父亲也会发生改变
					console.log("a8")
				}
				
				console.log(s)
				// s.say();
				// s.car();
				s.car();
				f.car();

2.借用构造函数继承

借用构造函数的技术(有时候也叫做伪类继承或经典继承)。这种技术的基本思想相当简单, 即在:子类构造函数的内部调用父类构造函数。 别忘了,函数只不过是在特定环境中执行代码的对象,因此通过使用apply()和call()方法也可以在新创建的对象上执行构造函数

function Fn(name,age,sex){
			this.name = name;
			this.age = age;
			this.sex = sex;
			this.oa = function(){
				console.log(111)
			}
		}
		Fn.prototype.say = function(){
			console.log(this.name,this.age,this.sex)
		}
		
		var f = new Fn('张三',18,"未知")
		f.say();
		
		function Son(name,age,sex){
			// Fn.call(this,name,age,sex);    
//调用Fn函数,在本次调用时改变Fn内的this指向(指向Son 将向Fn内添加的属性 添加至Son中),将参数
//传递过去
			Fn.apply(this,[name,age,sex]);    
//调用Fn函数 在本次调用时改变Fn内的this指向(指向Son 将向Fn内添加的属性 添加至Son中) 将参数传
//递过去
		}
		
		var s = new Son('贾师傅',18,'哦念经四川');
		console.log(s)

3.组合继承

组合继承,指的是将原型链和借用构造函数技术组合到一起,从而发挥两者之长的一种继承模式。其背后的思想是使用原型链实现对原型上的公共属性和方法的继承,而通过借用构造函数继承来实现对父类私有属性的继承。这样,即通过在父类原型上定义方法实现了函数复用,又能够保证每个实例都有父类的私有属性。

组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,称为JavaScript中最常用的继承模式。

function Fn(name,age,sex){
			this.name = name;
			this.age = age;
			this.sex = sex;
		}
		Fn.prototype.car = function(){
			console.log('我是有一辆小汽车')
		}
		Fn.prototype.dog = function(){
			console.log('家有恶犬')
		}
		
		var f = new Fn('沾伞',18,'难受')
		console.log(f)
		
		
		function Son(name,age,sex){
			Fn.call(this,name,age,sex)
		}
		
		//对Fn函数的原型对象进行遍历     将Fn原型对象中的每个属性或方法 添加至 Son的原型对象中
		// for(var i in Fn.prototype){
		// 	Son.prototype[i] = Fn.prototype[i];
		// }
		// Son.prototype.constructor = Son;
		// Son.prototype = new Fn();
		
		
		var s = new Son('请问',21,'在撒的');
		s.__proto__.car = 123;
		console.log(s)

组合继承的问题: 无论在什么情况下,都会调用两次父类的构造函数:一次是在创建子类原型的时候,另一次是在子类构造函数内部

4.寄生组合继承

组合继承方法我们已经说了,它的缺点是两次调用父级构造函数,为了解决这个问题只能砍掉一次调用。因此使用Object.create方法进行继承

function Fn(name,age,sex){
			this.name = name;
			this.age = age;
			this.sex = sex;
		}
		Fn.prototype.say = function(){
			console.log('我会说话')
		}
		function Son(name,age,sex){
			Fn.call(this,name,age,sex);
		}
		
		Son.prototype = Object.create(Fn.prototype); // 这里只将父类的prototype拿过来并使用Object.create(是一种创建对象的方式,它会创建一个中间对象)
		Son.prototype = new Fn();
		Son.prototype.constructor = Son;
		
		
		var f = new Fn('张三',18,'男');
		var s = new Son('李四',20,'男');
		
		s.__proto__.__proto__.say = 123;
		
		console.log(f);
		console.log(s)

5.多重继承

JavaScript中不存在多重继承,那也就意味着一个对象不能同时继承多个对象,但是我们可以通过变通方法来实现。

function Fn(name,age,sex){
			this.name = name;
			this.age = age;
			this.sex = sex;
		}
		function Fun(){
			this.car = '宝马';
			this.lou = '别野'
		}
		Fn.prototype.car = function(){
			console.log('我是有一辆小汽车')
		}
		Fn.prototype.dog = function(){
			console.log('家有恶犬')
		}
		
		var f = new Fn('沾伞',18,'难受')
		console.log(f)
		
		
		function Son(name,age,sex){
			Fn.call(this,name,age,sex)
			Fun.call(this);
		}
		//对Fn函数的原型对象进行遍历 将Fn原型对象中的每个属性或方法 添加至 Son的原型对象中

		// for(var i in Fn.prototype){
		// 	Son.prototype[i] = Fn.prototype[i];
		// }
		// Son.prototype.constructor = Son;
		
		
		var s = new Son('请问',21,'在撒的');
		s.__proto__.car = 123;
		console.log(s)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值