为什么叫伪经典继承呢,因为javaScript中真的没有类。
//两种都会打印:Jumper is running!
//Jumper bounces high into the sky!
这里是两个伪经典继承的例子,第一种看上去更容易明明白,第二种只是在第一种的基础上对继承的细节进行了封装,使用起来更简单友好。多的不说,将代码自己写一遍自然就懂了。注释也有必要的说明。
// --------- the base object ------------
//没有对继承细节进行封装
function Animal(name) {
this.name = name;
}
// methods
Animal.prototype.run = function() {
alert(this + " is running!");
}
Animal.prototype.toString = function() {//关于toString见另一篇文章:javaScript valueOf和toString方法在不同场景被调用进行数据转换
return this.name;
}
// --------- the child object -----------
function Rabbit(name) {
Animal.apply(this, arguments);
}
Rabbit.prototype = Object.create(Animal.prototype);//inherit(Animal.prototype);
//inherit是跨浏览器的,Object.create IE9后才兼容
Rabbit.prototype.constructor = Rabbit;
// override
Rabbit.prototype.run = function() {
Animal.prototype.run.apply(this);//调用被子类覆盖了的父类方法
alert(this + " bounces high into the sky!");
}
var rabbit = new Rabbit('Jumper');
rabbit.run();
function inherit(proto) {
function F() {}
F.prototype = proto
return new F
}
//将继承的细节进封装,这样可以更友好的使用父对象的方法,如Rabbit.parent.constructor、Rabbit.parent.run等
function extend(Child, Parent) {
Child.prototype = inherit(Parent.prototype)
Child.prototype.constructor = Child//手动修正子类的constructor属性
Child.parent = Parent.prototype
}
//将父类prototype赋给一个空函数再返回空函数的实例赋给子类的prototype,而不是直接将父类对象赋给子类prototype
//因为直接使new Animal()父类对象需要传入参数,使用inherit是很好的处理方式。但是经我测试new Animal()时不传入参数同样能正确执行.在判定浏览器的兼容性后可以使用Object.create代替,现代浏览器大多已经支持
function inherit(proto) {
function F() {}
F.prototype = proto
return new F
}
// --------- the base object ------------
function Animal(name) {
this.name = name;
}
// methods
Animal.prototype.run = function() {
alert(this + " is running!");
}
Animal.prototype.toString = function() {
return this.name;
}
// --------- the child object -----------
function Rabbit(name) {
Rabbit.parent.constructor.apply(this, arguments);
}
// inherit
extend(Rabbit, Animal);
// override
Rabbit.prototype.run = function() {
Rabbit.parent.run.apply(this);//调用被子类覆盖了的父类方法
alert(this + " bounces high into the sky!");
}
var rabbit = new Rabbit('Jumper');
rabbit.run();
//两种都会打印:Jumper is running!
//Jumper bounces high into the sky!
//private类型的数据:这种模式中不支持private 类型的数据
//protected类型的数据:以下划线开头的命名代表protected类型的数据,不应该从外部对其进行访问(技术上是可以访问的)
//static类型的数据:见另一篇文章:javaScript中的static类型数据