简单的意译,JavaScript仿照传统的继承方式进行继承(如:Java的继承方式)
JavaScript是一种弱类型,面向对象的语言,正因为如此,它使用原型继承,而不是经典的继承。这些让使用传统的面向对象语言,如C++和Java的程序员很不能理解。 JavaScript的原型继承比传统的继承有着更强的表现力。
不过要问,我们为什么关心继承呢?主要有两个原因:
第一:类型的便利。我们想要的语言系统自动转化相似类的引用。强类型语言(如Java),类型系统要求对对象的引用要进行显示的类型转换,而对于弱类型的JavaScript中的对象引用不存在转换问题。
第二:代码的重用。有一定数量的对象实现了相同的方法,或者一个对象与其他对象具有共同部分,其余都是给该对象增加或减少少量的方法,这时候就用继承来提取公共部分,这将是非常有用。而JavaScript的Prototype继承更加有用。
下面是用JavaScript来模仿传统的继承。
Java示例:类Parenizor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
class
Parenizor{
private
String value;
public
Parenizor(value){
this
.value=value;
}
public
void
setValue(value){
this
.value=value;
}
public
String getValue(){
return
this
.value;
}
public
String toString(){
return
"Parenizor[value:"
+value+
"]"
;
}
}
|
JavaScript示例:原型对象Parenizor
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function
Parenizor(value) {
this
.setValue(value);
}
Parenizor.method(
'setValue'
,
function
(value) {
this
.value = value;
return
this
;
});
Parenizor.method(
'getValue'
,
function
() {
return
this
.value;
});
Parenizor.method(
'toString'
,
function
() {
return
'('
+
this
.getValue() +
')'
;
});
|
上面JavaScript模仿的例子还不能使用,method是Function内置对象的方法,而该方法是用户自己为Function对象添加的原型方法。因此要添加如下方法,上面JavaScript模仿Java的类定义中的方法才能正常使用。
Function.prototype.method方法如下:
1
2
3
4
|
Function.prototype.method =
function
(name, func) {
this
.prototype[name] = func;
return
this
;
};
|
关于继承:再次扩充了函数,使它继承了父类的一个实例并将它用于一个新的原型,并且修改constructor部分,并将uber方法一并添加到这个原型中来了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
Function.method(
'inherits'
,
function
(parent) {
this
.prototype =
new
parent();
var
d = {},
p =
this
.prototype;
this
.prototype.constructor = parent;
this
.method(
'uber'
,
function
uber(name) {
if
(!(name
in
d)) {
d[name] = 0;
}
var
f, r, t = d[name], v = parent.prototype;
if
(t) {
while
(t) {
v = v.constructor.prototype;
t -= 1;
}
f = v[name];
}
else
{
f = p[name];
if
(f ==
this
[name]) {
f = v[name];
}
}
d[name] += 1;
r = f.apply(
this
, Array.prototype.slice.apply(arguments, [1]));
d[name] -= 1;
return
r;
});
return
this
;
});
|
关于多继承:
使用函数的Prototype对象是可以实现多继承的,通过使用多个类来构造一个新类,不过这样的多重继承会很复杂和不易维护。
1
2
3
4
5
6
7
|
Function.method(
'swiss'
,
function
(parent) {
for
(
var
i =
1
; i < arguments.length; i +=
1
) {
var
name = arguments[i];
this
.prototype[name] = parent.prototype[name];
}
return
this
;
});
|
swiss方法中循环访问arguments数组中的元素。对于每一个名称,它从父级prototype中复制一个member到它的新类的prototype中去。
使用方式:
1
|
ZParenizor.swiss(NumberValue,
'setValue'
,
'setRange'
);
|
只需要为ZParenizor添加上需要的NumberValue的方法setValue和setRange.
译文末:
传统意义上的对象是固化的,只有新建一个类才能添加对象的成员。但是在JavaScript中,对象是开放的,能够非常方便的添加成员。
本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1273037,如需转载请自行联系原作者