js常见的继承

提示:本文对js常见的继承做了个小结,分为原型链继承,构造函数继承,组合继承,extends继承


提示:以下是本篇文章正文内容,下面案例可供参考

一、原型链继承(prototype)

  1. 特点:将父类的实例作为子类的原型,即Son.prototype = new Father()
  2. 优点:(1)(不但继承父类构造函数中的属性和方法)可以继承父类原型上的方法或属性;
    (2)实例是子类的实例,也是父类的实例
  3. 缺点:(1)子类的实例共享了父类构造函数的引用属性;(2)无法实现继承多个,只能单一继承;(3)创建子类实例时,无法向父类构造函数传参
function Animal(name,age) {
	this.name = name;
	this.age = age;
	this.hobby = ['eat','sleep','play'];
	this.getAge = function () {
		console.log('my age is' + this.age);
	}
}

Animal.prototype.sleep = function () {
	console.log(this.name + 'is sleeping');
}

function Dog(height) {
	this.height = height;
}

// 原型链继承:把Animal的实例挂载到Dog身上
Dog.prototype = new Animal();
Dog.prototype.name = dog;

let d1 = new Animal(); // 父类构造函数不能传参
d1.hobby.push('drink'); 
console.log(d1 instanceof Dog);   //true 实例既是子类的也是父类的
console.log(d1 instanceof Animal);  //true
let d2 = new Animal();
d1.sleep();  // dog is sleeping 子类可以访问父类原型中的所有属性和方法
console.log(d1.hobby,d2.hobby);  // ['eat','sleep','play','drink']  ['eat','sleep','play','drink'] 子类的实例共享了父类构造函数的引用属性


二、构造函数继承(call)

  1. 特点:在子类函数中调用父类构造函数,并使用call改变this指向
  2. 优点:(1)父类的引用属性不会被共享(优化原型链继承);(2)创建子类实例时,可以向父类传递参数;
  3. 缺点:(1)(只能继承父类构造函数中的属性和方法)不能继承父类原型中的属性和方法,无法实现复用
    (2)实例只是子类构造函数的实例,不是父类的实例
function Parent(){
	this.name = name;
	this.age = age;
	this.getName = function () {
		console.log(this.name + 'is my name');
	}
}
// 父类原型上的方法不能被继承
Parent.prototype.sleep = function () {
	console.log(this.name + 'is sleeping');
}

function Child () {
// 在子类中使用父类构造函数,并通过call改变this指向
	Parent.call(this,name,age);
	this.score = score;
}

let child = new Child('小明',20,98); //可以向父类构造函数传参
console.log(child  instanceof Child); // true 实例只是子类的实例并不是父类的
console.log(child  instanceof Parent);  //false
child.getName();  // 小明 is my name
child.sleep();   //报错,子类不能继承父类原型中的方法

三、组合继承(prototype+call)

  1. 特点:使用原型链继承父类原型上的属性和方法,使用构造函数继承父类构造函数中的属性和方法
  2. 优点:(1)创建子类实例时,父类构造函数可以传入参数(2)继承父类原型上的属性和方法(3)既是子类的实例,也是父类的实例;(4)不存在父类引用属性共享问题
  3. 缺点:
function Animal() {
	this.name = name;
	this.age = age;
	this.eat = function() {
		console.log(this.name + 'want eat lunch');
	}
}
Animal.prototype.sleep = function () {
	console.log(this.name + 'is sleeping');
}

function Cat(weight) {
	Animal.call(this,name,age);
	this.weight = weight;
}
// 组合继承
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;

let cat = new Cat ('蔡蔡',3,10);
cat.eat(); // 蔡蔡 want eat lunch
cat.sleep(); //蔡蔡 is sleeping  可以访问父类原型上的属性与方法
function SuperType(name) {
	this.name = name;
	this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function() {
	alert(this.name);
}

function SubType(name, age) {
	// 继承属性
	SuperType.call(this, name);
	this.age = age;
}

// 继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
	alert(this.age);
};

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27 

四、extends继承

class Person{
	constructor(name,age){
		this.name = name;
		this.age = age;
	};
	getName(){
		console.log(this.name);
	}
}

class Student extends Person{
	constructor(x,y,score){
		super(x,y);
		this.score = score;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值