2020-12-22

js实现的继承几种方式

原型继承

1,通俗理解:就是子对象拥有父对象的属性和方法 继承可以i提高代码的复用性
2,js里的继承只要依靠的是原型链,让原型对象的值,等于另一个类型的实例,实现了继承,另外一个类型的原型在指向第三个类型的实例,以此类推就形成了一个原型链:

function Animal(newSex){
		this.sex = newSex;
	}
	
	Animal.prototype.eat = function(){
		console.log("Animal eat");
	}
	
	function Human(newName){
		this.name = newName;
	}
	
	Human.prototype = new Animal("雌雄同体");
	Human.prototype.makeTools = function(){
		console.log("Human makeTools");
	}

//凭什么h 可以访问 子类的属性的方法 和父类 的属性的方法 :原型图
	let h = new Human("老王");
	h.sex = "男";
	console.log(h.sex);
	console.log(h.name);
	h.eat();
	h.makeTools();
	

原型链的继承 :

1,让子对象的原型指向父对象的实例,父对象原型指向爷爷对象的实例 以此类推就是实现了原型链的继承

	function Animal(newSex){
		this.sex = newSex;
	}
	function Human(newName){
		this.name = newName;
	}
	// 父对象的原型指向爷爷对象的实例
	Human.prototype = new Animal("雌");
	function  Student(newScore){
		this.score = newScore;
	}
	// 子对象的原型指向父对象的实例 
	Student.prototype = new Human("老王");

原型继承中的注意事项:

1,先定义原型的继承关系,再添加子类的自定义的方法或者属性,
2,利用原型链的继承,给子类添加原型的方法时,不可以重新写 prototype ,也就是 由父类派生的子类的属性,无法初始化:

call 和apply 继承

1,apply 和call是函数对象的该方法,他们可以改变this 的指向
2,fun.apply(“改变的this指向”,[“原来的fun的参数1”,“原来的fun的参数2”…])
3,fun.call(document,3,3);// call 参数可以拆开

// function fun(a,b){
	// 	console.log(this);
	// 	console.log(a+b);
	// }
	//fun.apply("改变的this指向",["原来的fun的参数1","原来的fun的参数2"...])
	//fun.apply(document,[1,2]);  //apply 参数为数组形式
	//fun.call(document,3,3);// call 参数可以拆开
function Person(newId,newName){
		this.id = newId;
		this.name = newName;
		
	}
	Person.prototype.eat = function(){
		console.log("Person eat");
	}
	function Student(newId,newName,newScore){
		//借用父类的构造方法
		Person.call(this,newId,newName);
		this.score = newScore;
	}
	let s = new Student(1,"老王",100);

弊端:
1,无法继承父类原型的属性和方法
2,单独使用这种借用的模式 ,所有的继承的属性 和方法都要在父类型的对象 函数里定义,特别实例共享的属性和方法 也在构造函数里,那么这样就会浪费内存。

混合继承

1,结合前两种方式:原型链式继承和Call()/Apply()方式继承,我们就能解决前面提出的那些问题。
利用原型链继承共有的属性和方法,利用Call/Apply来初始化自己的但是和父类型同名的属性或方法。

function Person(newId,newName){
		this.id = newId;
		this.name = newName;
	}
	Person.prototype.eat = function(){
		console.log("Person eat");
	}
	function Student(newId,newName,newScore){
		Person.call(this,newId,newName);
		this.score = newScore;
	}
	Student.prototype = new Person();
	Student.prototype.study = function(){
		console.log("Student study");
	}
	
	let s = new Student(1,"老王",99);
	console.log(s.id,s.name,s.score);
	s.eat();
	s.study();

ES6的继承

1,class 子类 extends 父类{}
2,注意切记 super 这句代码放在函数的第一行

class Person{
		constructor(newId,newName) {
			this.id = newId;
			this.name = newName;  
		}
		eat(){
			console.log("Person eat");
		}
	}
	class Student extends Person{
		constructor(newId,newName,newScore) {
		    super(newId,newName);
			this.score = newScore;
		}
	}
        let s = new Student(1,"laowang");
        console.log(s.id,s.name);
	    s.eat();
		s.study();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值