一. 对象冒充(又分为2种方式): 对象冒充方式的继承,只能继承父类函数内的属性,不能继承父类原型中的属性
方式一: 1. 让父类的构造函数成为子类的方法;
2. 给子类的这个方法传入父类所拥有的属性,这就继承了父类的一些属性;
3. 再在子类中删除这个方法;
function Child(name, age) {
this.obj = Parent;
this.obj(name, age);
delete this.obj;
}
方式二 : 用call或apply的方式继承
function Child(name, age) {
Parent.call(this, name, age);
}
注意: apply方法中是用数组传入参数
function Child(name, age) {
Parent.apply(this,[name, age]);
}
说明: 方式一的功能等价于方式二的功能;两种方式都使Child继承了Parent.
代码详解:
function Parent(name , age) {
this.name = name;
this.age = age;
this.sayName = function() {console.log(this.name);}
}
function Child(name, age) {
this.obj = Parent;
this.obj(name, age);
delete this.obj;
// Parent.call(this, name, age); 被注释的语句
}
var c = new Child("zhangsan", 21);
console.log(c.name);
Chiled函数---解释:
第一句: this.obj = Parent:
把Parent这个函数赋给obj,相当于obj就是一个函数,
第二句: this.obj(name, age);
给obj这个对象传入参数,此时obj拥有了完整的Parent属性,
又因为obj是Child这个函数的属性,所以就是把Parent付给了Child;
此时Child就完全拥有了Parent的属性.
第三句: delete this.obj;
上面两句已经使Child完全继承了Parent的属性,
所以接下来删除obj这个函数(obj是Parent函数的一个对象).
解释: Parent.call(this, name, age);
call里面的this代表的是Child所创建的对象;
call方法的调用(拿这句举例):
Parent调用了call这个方法,代表,Parent函数内部的this指向的
是传入call方法里面的对象.
所以上面这条语句的功能就是让Child继承了Parent的属性
二. 原型继承(这种方式的继承,是继承了父类函数内的属性,同时也继承了父类原型中的属性)
原理: 1. 使子类的原型指向父类的实例(通过new创建的对象); 2. 在子类函数中,通过父类的构造器constructor对子类的属性进行初始化.
function Person(name, age){
this.name = name;
this.age = age;
this.sayname = function(){
console.log(this.name);
}
}
Person.prototype.sayage = function () {
console.log(this.age);
};
function Child(name,age,sex){
//第二步: 下面这个congstructor指向的是父类(这其实是父类的constructor),用来继承到父类属性的初始化
this.constructor(name,age);
this.sex = sex;
}
//第一步: 使子类的原型指向父类的实例
Child.prototype = new Person();
var c1 = new Child();
c1.name = "zhangsan0";
c1.age = 20;
c1.sayname();
c1.sayage();
三. 混合方式的继承(混合call的方式和原型链的方式)
原理: 属性通过冒充对象的call方法继承,行为通过原型链的方式继承(通过这样的继承方式,似乎子类不能设置原型中的属性,这点不明白)
function Parent(name,age){
this.name = name;
this.age = age;
}
Parent.prototype.sayage = function () {
console.log(this.age);
};
Parent.prototype.sayname = function () {
console.log(this.name);
};
function Child(name,age){
//属性通过call方法继承
Parent.call(this,name,age);
this.sex = "meal";
}
//行为通过原型继承
Child.prototype = new Parent();
var c1 = new Child();
var c2 = new Child();
c1.name = "Tom";
c2.name = "Tony";
//返回Tom
c1.sayname();
//返回Tony
c2.sayname();