[Javascript] 继承 (原型继承, 类继承)

时间:2022-08-24 23:09:10

(1) 原型链继承

在js中没有类的概念, 所以继承的话, 使用原型链继承

B.prototype=new A();

4步:
[1] 初始化对象
[2] B.prototype=A.prototype
[3] A作用域给B A.call(B.prototype)
[4] 返回对象
<script type="text/javascript">
function Parent(){
this.property="parent_value";
}
Parent.prototype={
property:"parent_value_prototype",
get:function(){
return this.property;
}
}
function Child(){
this.property="child_value";
}
Child.prototype={
property:"child_value_prototype",
get:function(){
return this.property;
}
}

Child.prototype=new Parent();//继承
var child=new Child();
console.log(child.get());
//child_value
</script>
<script type="text/javascript">
function Parent(){
this.property="parent_value";
}
Parent.prototype={
property:"parent_value_prototype",
get:function(){
return this.property;
}
}
function Child(){
//this.property="child_value";
}
Child.prototype={
property:"child_value_prototype",
get:function(){
return this.property;
}
}

Child.prototype=new Parent();//继承

var child=new Child();
console.log(child.get());
//parent_value
</script>
<script type="text/javascript">
function Parent(){
//this.property="parent_value";
}
Parent.prototype={
property:"parent_value_prototype",
get:function(){
return this.property;
}
}
function Child(){
//this.property="child_value";
}
Child.prototype={
property:"child_value_prototype",
get:function(){
return this.property;
}
}

Child.prototype=new Parent();//继承

var child=new Child();
console.log(child.get());
//parent_value_prototype
</script>
<script type="text/javascript">
function Parent(){
//this.property="parent_value";
}
Parent.prototype={
//property:"parent_value_prototype",
get:function(){
return this.property;
}
}
function Child(){
//this.property="child_value";
}
Child.prototype={
property:"child_value_prototype",
get:function(){
return this.property;
}
}

Child.prototype=new Parent();//继承

var child=new Child();
console.log(child.get());
//undefined
</script>

Resullt:
继承了Parent的Child,
[1] 会从Child的实例中找
[2] 再从Parent实例中找
[3] 再从Parent.prototype中找
( 不会从Child.prototype中找)


(2) 原型链继承 优点+缺点

优点:

  父类的实例属性得到了继承

缺点:

[1] 父类实例属性为引用类型, 修改会改变所有的之类

 Child继承了Parent后,Child.prototype就成了Parent的一个实例,因此它也拥有name属性
<script type="text/javascript">
function Parent(){
this.name=["yoonA","jessica"];
}
function Child(){
}
//继承
Child.prototype=new Parent();

//实例child1
var child1=new Child();
//child1修改了值
child1.name.push("krystal");
console.log(child1.name);
//["yoonA", "jessica", "krystal"]


//实例child2
var child2=new Child();
//但是child2的值也改变了
console.log(child2.name);
//["yoonA", "jessica", "krystal"]
</script>

[2] 传参问题

在创建子实例时候,不能向父类传参

<script type="text/javascript">
function Parent(name){
this.name=name;
}
Parent.prototype.say=function(){
console.log(this.name);
}
function Child(name){
}
//继承
Child.prototype=new Parent();
var c=new Child("krystal");
c.say();
//undefined
</script>

(3) 类继承

Parent.call(this,name);
构造函数的应用, 子内部call 调用父类的构造器, 实现传参问题

  function Parent(name){
this.name=name;
}
Parent.prototype.say=function(){
console.log(this.name);
}
function Child(name){
Parent.call(this,name);
}
//Child.prototype=new Parent();
var c=new Child("krystal");
console.log(c.name);
c.say();

[Javascript] 继承 (原型继承, 类继承)

优点+缺点:

优点: 可以传参
缺点: 但是Child子 无法使用 Parent父的Prototype的内容


(4) 原型链+类继承

Parent.call(this,name);

传参, 实现对实例属性的继承

Child.prototype=new Parent();

实现原型属性和方法的继承

function Parent(name){
this.name=name;
this.school=["hkbu","hku"];
}
Parent.prototype.say=function(){
console.log(this.name);
}
function Child(name){
Parent.call(this,name);
// 类继承: 继承实例属性
}
Child.prototype=new Parent();
// 原型继承: 继承原型的方法和属性

var c=new Child("krystal");
console.log(c.name);
c.say();

c.school.push("NEU");
console.log(c.school);

var c2=new Child("jessica");
console.log(c2.school);

Result:

[Javascript] 继承 (原型继承, 类继承)