对象之间的继承有以下几个方法:
用call和apply(不推荐单独使用,定义在prototype中的属性和方法不能继承)
prototype模式(注意prototype需要先继承后定义)
传统prototype模式(推荐,关键点是Child.prototype = new Parent.prototype
以及重新改变Child.prototype.constructor
)
利用空对象间接继承(只继承prototype中的属性,关键点在于利用一个空的构造函数当中介)
拷贝继承(不推荐单独使用,for循环逐一拷贝)
以上推荐使用传统prototype模式以及call和apply与拷贝继承相配合的模式
function Chinese() {
this.nationality = "Chinese";
}
function Person(name, age) {
Chinese.apply(this); //这里改变了Chinese中this的指向
this.name = name;
this.age = age;
}
var p1 = new Person("Oli", 18);
console.log(p1.nationality); //Chinese
function Chinese() {
this.nationality = "Chinese";
}
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = new Chinese(); //这里因为在prototype中使用了new,则会指向Chinese
console.log(Person.prototype.constructor); //Chinese(){}
Person.prototype.constructor = Person; //这里需要把constructor构造函数重新改为Person
console.log(Person.prototype.constructor); //Person(){}
var p1 = new Person("Oli", 18);
console.log(p1.nationality); //Chinese
需要注意的是:在继承中,如果替换了prototype,那么新的prototype必须修改constructor属性,将这个属性指回到原来的构造函数。
function Chinese() {}
Chinese.prototype.nationality = "Chinese";
function Person(name, age) {
this.name = name;
this.age = age;
}
function F(){}; //空对象几乎不占用内存
F.prototype = Chinese.prototype;
Person.prototype = new F();
Person.prototype.constructor = Person;
Person.prototype.sayName = function() { //Person的prototype中的方法和属性需要在继承之后定义
console.log(this.name);
};
var p1 = new Person("Oli", 18);
console.log(p1.nationality); //Chinese
p1.sayName(); //Oli
function extend(Child, Parent) {
var F = function() {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype; //用于访问父对象的prototype,可用可不用
}
举例:
function extend(Child, Parent) {
var F = function() {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
function Chinese() {}
Chinese.prototype.nationality = "Chinese";
function Person(name, age) {
this.name = name;
this.age = age;
}
extend(Person, Chinese);
Person.prototype.sayName = function() {
console.log(this.name);
};
var p1 = new Person("Oli", 18);
console.log(p1.nationality); //Chinese
p1.sayName(); //Oli
使用下面的函数逐一将prototype的属性和函数拷贝到对象中:
function extend(Child, Parent) {
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
}
传统prototype模式继承(例子)
function Parent() {
this.name = "thisIsName";
}
Parent.prototype.sayName = function() {
return this.name;
};
function Child() {
this.age = "thisIsAge";
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
Child.prototype.sayAge = function() {
return this.age;
};
var c = new Child();
console.log(c.name);
console.log(c.age);
console.log(c.sayName());
console.log(c.sayAge());
function extend(C, P) {
var p = P.prototype;
var c = C.prototype;
for(var i in p){
c[i] = p[i];
}
c.uber = p;
}
function Parent() {
this.name = "thisIsName";
}
Parent.prototype.sayName = function() {
return this.name;
};
function Child() {
Parent.apply(this); //继承构造函数内的属性和方法
this.age = "thisIsAge";
}
Child.prototype.sayAge = function() {
return this.age;
};
extend(Child, Parent); //不需要先继承后定义
var c = new Child();
console.log(c.name);
console.log(c.age);
console.log(c.sayName());
console.log(c.sayAge());