JS 类继承和原型继承区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS 类继承和原型继承区别相关的知识,希望对你有一定的参考价值。
最近研究JS 的继承问题,知道常用的两种继承方式,一是类继承,而是原型继承。看了一些文章,但是有点混淆,发型他们很相似的呢,想知道两者的区别到底是怎么样的,求指教。
原型继承方式:
function parent();
parent.prototype.Pname='Parent';
function child()
child.prototype=new parent(); //将子类的原型指向父类
child.prototype.Cname='child';
这样就实现了原型继承。
类继承方式:
function parent2(sparam)
this.param=sparam;
this.getParam=function()
return this.param;
;
function child2(cparam,cname)
parent2.call(this,cparam); //调用父类构造函数
this.name=cname;
child2.prototype=new parent2('param'); //继承父类
child2.prototype.getName=function()
return this.name;
这样完成类继承。
看完就觉得迷糊,感觉是类似的啊,没有啥本质的区别,只是一个带参数,一个不能带参数。请高手指点指点。
原型式继承是借助已有的对象创建新的对象,将子类的原型指向父类,就相当于加入了父类这条原型链
而你的 下面这段代码不是严格意义上的类式继承,按照Nicholas C.Zakas的说法,这个应该叫做组合式继承。它调用了两次parent2()。第一次是 child2.prototype=new parent2('param'); child2就会得到两个属性param,getParam(),他们都是parent2的属性,但是他们在child2的原型中。第二次是parent2.call(this,cparam); 这次又在新对象上创建了实例属性param,getParam()。于是,这两个属性就屏蔽了原型中的两个同名属性。这有什么好处呢,就是你在构建一个child3时也继承parent2()的属性,还可以定义自己的属性。与此同时他长的就和他兄弟不同了,但又有一样的“血统(使用父类的方法)”。
纯手打,欢迎继续讨论追问
嗯 第二种我说的类继承确实不严格,但看到不少博客把这种继承叫做类继承。我查看了一些教材,很少有说类继承的,也多是组合继承,请问您有见过严格的类继承吗?应该是什么样的?
追答严格的类继承不是很常见,一般都是组合着用。看下例:
function Super()this.colors=["red","blue"];
function Sub()
Super.call(this);
这就是类式继承,这个有一个缺点就是 方法在构造函数内创建,函数的复用就无从谈起了,而且还有一个问题,就是在超类原型中定义的方法对子类是不可见的。
还有就是子类会复制父类的属性,如下:
var a=new Sub();a.colors.push("black");
console.log(a.colors);//-----> "red,blue,black"
var b=new Sub();
console.log(b.colors);//-----> "red,blue"
其实最常用的还是组合继承,至于用什么继承模式,完全不用纠结,这要看具体使用环境
参考技术A javascript函数不会对传参情况进行检测,所以这个不是重点。借用父类构造函数,可以获得父类构造函数里面的相同属性和方法。例如第二种,子类实例拥有param、getParam两个成员,而第一种是没有的。追问那这样说来,类继承中 child2.prototype=new parent2('param'); 这句是完全可以不用的嘛,直接通过call得到了父类的属性和方法,可以不再需要改变子类的原型,对吧?
还有其他什么区别吗?
如果不用的话继承不到父类的原型
参考技术B 1.JS类式继承:/* -- 类式继承 -- */
//先声明一个超类
function Person(name)
this.name = name;
//给这个超类的原型对象上添加方法 getName
Person.prototype.getName = function()
return this.name;
//实例化这个超
var a = new Person('Darren1')
console.log(a.getName());//Darren1
//再声明类
function Programmer(name, sex)
//这个类中要调用超类Person的构造函数,并将参数name传给它
Person.call(this, name);
this.sex = sex;
//这个子类的原型对象等于超类的实例
Programmer.prototype = new Person();
//因为子类的原型对象等于超类的实例,所以prototype.constructor这个方法也等于超类构造函数,你可以自己测试一下,如果没这一步,console.log(Programmer.prototype.constructor这个是Person超类的引用,所以要从新赋值为自己本身
console.log(Programmer.prototype.constructor);
/*function Person(name)
this.name = name;
*/
Programmer.prototype.constructor = Programmer;
console.log(Programmer.prototype.constructor);
/*function Programmer(name, sex)
Person.call(this, name);
this.sex = sex;
*/
//子类本身添加了getSex 方法
Programmer.prototype.getSex = function()
return this.sex;
//实例化这个子类
var _m = new Programmer('Darren2', 'male');
//自身的方法
console.log(_m.getSex());//male
//继承超类的方法
console.log(_m.getName());//Darren2
2.JS原型继承:
/* -- 原型式继承 -- */
//clone()函数用来创建新的类Person对象
var clone = function(obj)
4
var _f = function() ;
//这句是原型式继承最核心的地方,函数的原型对象为对象字面量
_f.prototype = obj;
return new _f;
//先声明一个对象字面量
var Person =
name: 'Darren',
getName: function()
return this.name;
//不需要定义一个Person的子类,只要执行一次克隆即可
var Programmer = clone(Person);
//可以直接获得Person提供的默认值,也可以添加或者修改属性和方法
alert(Programmer.getName())
Programmer.name = 'Darren2'
alert(Programmer.getName())
//声明子类,执行一次克隆即可
var Someone = clone(Programmer);
以上是关于JS 类继承和原型继承区别的主要内容,如果未能解决你的问题,请参考以下文章