(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();
优点+缺点:
优点: 可以传参
缺点: 但是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: