js中的继承方式

JavaScript继承实现的方式也很多,主要分ES5和ES6的继承的实现

  • ES5实现继承主要是基于prototype来实现的
    • 原型链继承:用子类的原型链等于父类的实例对象
    • 借用构造函数继承(call或者apply的方法来实现继承)
    • 组合继承是结合原型链继承和借用构造函数继承
    • 寄生组合继承
  • ES6继承
    • 用class关键字定义类,用extend关键字继承类,⽤super()表示⽗类

原型链继承(易于实现,不能传参)

	//父类
	function Person(name,age){
		this.name = name || 'unknow'
		this.age = age || 0
	}

	//子类
	function Student(name){
		this.name = name
		this.score = 80
	}

	//继承
	Student.prototype = new Person();

	var stu = new Student('lucy');
	console.log(stu.name);  //lucy  --子类覆盖父类的属性
	console.log(stu.age);   // 0    --父类的属性
	console.log(stu.score);  // 80   --子类自己的属性

但是原型链继承有一个缺点,就是如果属性是引用类型的话,会共享引用类型,请看下面代码:

	//父类
	function Person(){
		this.hobbies = ['music','reading']
	}

	//子类
	function Student(){
	}

	//继承
	Student.prototype = new Person();

	var stu1 = new Student();
	var stu2 = new Student();

	stu1.hobbies.push('basketball');

	console.log(stu1.hobbies);  // ["music", "reading", "basketball"]
	console.log(stu2.hobbies);  //  ["music", "reading", "basketball"]

我们可以看到,当我们改变stu1的引用类型的属性时,stu2对应的属性也会跟着更改,这就是原型链继承的缺点—引用属性会被所有实例共享。

为了解决原型中包含引用类型值的问题,开始使用借用构造函数:构造函数继承

function SuperType() {
    this.colors = ["red", "blue", "green"];
}
 
function SubType() {
    //继承SuperType
    SuperType.call(this);
}
 
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green" 

使用构造函数继承就可以避免引用类型被所有实例共享的问题

		//父类
	function Person(){
		this.hobbies = ['music','reading']
	}

	//子类
	function Student(){
		Person.call(this);
	}

	var stu1 = new Student();
	var stu2 = new Student();

	stu1.hobbies.push('basketball');

	console.log(stu1.hobbies);  // ["music", "reading", "basketball"]
	console.log(stu2.hobbies);  //  ["music", "reading"]

组合继承:普通属性使用构造函数继承,函数使用原型链继承。

	//父类
	function Person(name){
		this.hobbies = ['music','reading'];
	}

	Person.prototype.say = function(){
		console.log('i am a person');
	}
	//子类
	function Student(name){
		Person.call(this);  //构造函数继承(继承属性)
	}

	Student.prototype = new Person();  //原型继承(继承方法)

	var stu1 = new Student('lucy');
	var stu2 = new Student('lili');

	stu1.hobbies.push('basketball');

	console.log(stu1.hobbies);  // ["music", "reading", "basketball"]
	console.log(stu2.hobbies);  // ["music", "reading"]

寄生组合继承:

function SuperType (name) {
	this.name = name;
	this.colors = ["red", "green", "blue"];
}
SuperType.prototype.sayName = function () {
	alert(this.name);
};
function SubType (name, age) {
	SuperType.call(this, name); 
	this.age = age;
}

// 下面这部分替代给子类原型赋值的过程,不调用父类构造函数,直接继承父类原型
var prototype = Object.create(SuperType.prototype);
prototype.constructor = SubType;
SubType.prototype  = prototype;

SubType.prototype.sayAge = function () {
	alert(this.age);
}

ES6中的class继承:

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y);
    this.color = color;
  }
  toString() {
    return this.color + ' ' + super.toString();
  }
}
let ins = new ColorPoint(1,2,'red');
console.log( ins.toString() ); /* red [object Object] */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值