Javascript属于弱类,没有所谓的类型转换,也没有像java那样成熟的继承方式。但是作为面对对象的语言,继承又是必不可少的。本文介绍三中js的继承方法,伪类继承、原型继承、函数化继承。
1.伪类继承
首先,定义一个构造器:
var Animal = function (name) {
this.name = name;
}
Animal.prototype.getName = function () {
return this.name;
}
var dog = new Animal('tidi');
现在有了行为像“类”的构造器函数,通过new,dog可以继承Animal的属性和方法。
但是有个缺点,那就是父类的所有属性都是公开的。除此之外,更糟糕的是,使用构造器函数存在一个严重的危害,当调用构造函数忘记使用new时,那么this不会绑定到一个新的对象上,dog无法使用Animal的属性和方法。但是当使用new时,又会有新的不足出现,那就是声明继承的时候创建的对象总要进行初始化,这种方式不好。改进方法就是定义一个新的空构造器。
例如:
var Animal = function () {
this.name = 'xxx';
}
Animal.prototype.getName = function () {
return this.name;
}
function f() {};
f.prototype = new Animal();
var dog = new f('tidi');
虽然这种方法解决了每次创建对象总要初始化的问题,但是也有新的问题出现,那就是:1.父类构造函数无法传参;2.父类的成员变量成了子类所有实例的公有变量。
2.原型链继承
原型继承摒弃了类,专注于对象。首先,构造一个有用的对象:
var Animal = {
name: 'leo',
get_name: function () {
return this.name;
},
set_name: function (name) {
this.name = name;
}
};
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
}
var dog = Object.create(Animal);
var cat = Object.create(Animal);
虽然原型链继承专注于对象,但是其继承思想还是通过构造器进行继承。
3.函数化继承
函数解决了伪类继承中无法得到私有变量和方法的缺点,同时,生成子类也不需要使用new方法。
例如:
var animal = function (spec) {
var that = {};
that.get_name = function () {
return spec.name;
}
that.bark = function () {
return spec.bark || 'no bark';
}
return that;
}
var dog = animal({name:'leo',bark:'wow'});
每一个子类,都可以在初始化的时候将其私有属性传递给父类,构造出其私有变量和方法,这种函数化的继承更灵活,也更方便。