Javascript 继承

一、构造继承

特点:
1.子类实例不会共享父类prototype中的属性和方法
2.创建子类实例时,可以向父类传参
3.可以实现多继承
缺点:
1.实例只是子类的实例,不是父类的实例
2.只能继承父类的实例属性和方法,不能继承父类的prototype中的属性和方法
3.产生冗余,每个子类都有父类实例函数的副本,影响性能

function Parent(username) {
	this.username = username;
	this.hello = function() {
		console.log(this.username);
	}
}

function Child(username, age) {
	//方法1
	this.method = Parent;   //1.创建临时变量指向Parent所指向的对象
	this.method(username);   //2.通过this.method执行Parent所指向的对象函数
	delete this.method;   //3.销毁this.method属性,此时Child拥有了Parent所有属性和方法
	//方法2
	Parent.call(this,username);   //1.使用call传递参数并执行Parent
	//方法3
	Parent.apply(this,new Array(username));   //2.使用apply传递参数数组并执行Parent
	this.age = age;
	this.getAge = function() {
		console.log(this.age);
	}
}

var parent = new Parent("Jason");
var child = new Child("Tom",18);
parent.hello();
child.hello();
child.getAge();

二、原型链继承

特点:
1.实例是子类的实例,也是父类的实例
2.父类的prototype新增属性和方法,子类都能访问到
3.简单,易于实现
缺点:
1.要为子类的prototype添加属性和方法,必须放在new Animal()语句之后执行,否则会被父类的prototype中的属性和方法覆盖
2.无法实现多继承
3.父类的prototype中的所有属性和方法被所有子类的实例共享
4.创建子类实例时,无法向父类构造函数传参

//将父类的prototype中的属性和方法追加到子类的prototype
function Parent() {}
Parent.prototype.hello = "hello";
Parent.prototype.sayHello = function() {console.log(this.hello);};

function Child() {}
Child.prototype = new Parent();  //关键
Child.prototype.constructor = Child;   //将子类的prototype的constructor指回自己
Child.prototype.world = "world";
Child.prototype.sayWorld = function() {console.log(this.world);}

var child = new Child();
child.sayHello();  //继承
child.sayWorld();

三、实例继承

特点:
1.不限制调用方法,不管是new Child()还是Child(),返回的对象都是相同的效果
缺点:
1.实例时父类实例,不是子类的实例
2.不支持多继承

function Parent(hello) {
  this.hello = hello; 
  this.sayGoodbye = function() {
    console.log('goodbye');
  }
}
function Child(name) {
	var instance = new Parent();
	instance.name = name || 'Tom';
	return instance;
}
var child = new Child('Jason');
console.log(child.name);
child.sayGoodbye();

四、组合继承(推荐)

核心:调用父类构造,继承父类的属性和方法,将父类实例作为子类原型,继承父类prototype对象的属性和方法;
特点:
1.可以继承父类实例属性和方法,也可以继承父类原型属性和方法
2.既是子类的实例,也是父类的实例
3.不存在引用属性共享问题
4.可传参
5.函数可复用
缺点:调用两次父类构造函数,生成了两份实例

//混合call、原型链方式
function Parent(hello) {
  this.hello = hello; 
  this.sayGoodbye = function() {
    console.log('goodbye');
  }
}
Parent.prototype.hello = "hello";
Parent.prototype.sayHello = function() {console.log(this.hello);};

function Child(hello, world) {
  Parent.call(this,hello);   //将Parent中的属性和方法追加到Child中
  this.world = world;
}
Child.prototype = new Parent();  //将Parent的prototype包含的属性和方法追加到Child.prototype
Child.prototype.constructor = Child;   //将子类的prototype的constructor指回自己
Child.prototype.sayWorld = function() {console.log(this.world);}

var child = new Child('Jason','bro');
child.sayHello(); //继承
child.sayWorld();
child.sayGoodbye();  //继承

五、拷贝继承

特点:
1.支持多继承
缺点:
1.效率低,内存占用高
2.无法获取父类不可枚举的方法

function Parent(name) {
  this.name= name; 
  this.sayGoodbye = function() {
    console.log('goodbye');
  }
}
function Child(name) {
	var parent= new Parent();
	for(var p in parent) {
		Child.prototype[p] = parent[p];
	}
	this.name = name || 'Tom';
}
var child = new Child();
console.log(child.name);
child.sayGoodbye();

六、寄生组合继承

核心:调用两次父类的构造时,不会初始化两次实例属性和方法,避免组合继承的缺点
特点:1.完美
缺点:1.实现较为复杂

function Parent(name) {
  this.name= name; 
  this.sayGoodbye = function() {
    console.log('goodbye');
  }
}
function Child(name) {
	Parent.call(this);
	this.name = name || 'Tom';
}
(function(){
	var Super = function(){};
	Super.prototype = Parent.prototype;
	Child.prototype = new Super();
})();

var child = new Child();
console.log(child.name);
child.sayGoodbye();

参考

Js如何实现继承: https://blog.csdn.net/it_sharp/article/details/87360386
Javascript 面向对象编程(一):封装 http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html
Javascript面向对象编程(二):构造函数的继承: http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html
Javascript面向对象编程(三):非构造函数的继承: http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance_continued.html
Js如何实现继承(js实现继承的五种方式):https://blog.csdn.net/it_sharp/article/details/87360386
JS实现继承的几种方式: https://www.cnblogs.com/humin/p/4556820.html

注:我写的内容是参考各位大牛写的文章,然后结合自己的理解而整理记录下来的。文章中的代码也是跑过无误后才贴上去的。如有不对之处,欢迎大家评论更正,谢谢!另外,对于上面参考文章的作者,如涉及侵权的请评论联系我做处理,感谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值