<disclaimer>
What follows is the fruits of a thought experiment. What I'm doing
isn't the issue; the symptoms are. Thank you.
</disclaimer>
我终于把注意力集中在JavaScript中的构造函数、原型和原型继承上了。但是下面的示例中的somethingspectular方法让我很烦:
function FinalClass() {
return {
FinalFunction : function() { return "FinalFunction"; },
TypeName : "FinalClass",
SomethingSpectacular : function() {
return FinalClass.prototype.SubFunction.call(this);
}
}
}
FinalClass.prototype = new SubClass();
FinalClass.constructor = FinalClass;
var f = new FinalClass();
-
JavaScript语言
显然地
对方法的扫描方式与对属性的扫描方式不同。也就是说,
f.SubFunction()
-
为了在一个原型上获得一个方法,你必须每次至少经历3个点操作。最终类点原型点子函数点调用。你明白了。
-
所以我的想法是,如果我写一个版本的
inherits
它将存根函数插入到子类中,子类为您委派回原型。例如,它将自动创建以下函数并将其添加到
FinalClass
function SubFunction() { SubClass.prototype.SubFunction.call(this); }
现在,我已经把一切都安排好了。这个
继承
Object.prototype
和
Function.prototype
Function
作为唯一的论据。这是基类。子类是通过分析
Object.prototype.inherits.caller
.
prototype
和
constructor
return
声明。
现在,我可以一步一步地完成所有这些代码,它工作得非常出色,直到我实例化为止
实例
子类的。那是事情变得不稳定的时候。以下是我使用Visual Studio 2008(SP1)和Internet Explorer 8观察到的内容:
-
在实例化之前,
BaseClass
不公开任何公共方法。这是意料之中的。通过类构造函数的
语句在实例化之前不会出现。我不介意。
-
在实例化之前,
SubClass
显示来自的方法
基类
. 这正是我所期望的。
-
基类
,它拥有我所期望的所有成员。它有自己的特点
typeName
和
BaseFunction
方法。
-
子类
返回
声明。基类中没有成员。在inherits方法中完成的将基类方法映射到子类的所有工作似乎都丢失了。
这里对我来说最大的谜团是我在执行继承时添加到子类的方法的消失。在它的执行过程中,我可以清楚地看到子类正在被修改,基类的函数正在被传播。但当我创建一个子类时,这些信息就不再存在了。
我假设这与构造器、事件顺序或其他我根本看不到的东西有关。
最后一句话:
代码
sti.objects.inherits = function inherits(baseClass) {
var subClass = sti.objects.inherits.caller;
var baseClassName = sti.objects.getTypeName(baseClass);
var methods = sti.objects.getMethods(baseClass);
if(!sti.objects.isDefined(baseClass.typeName))
baseClass.typeName = baseClassName;
var subClass = sti.objects.inherits.caller;
var subClassName = sti.objects.getTypeName(subClass);
var temp = function() {};
temp.prototype = new baseClass();
subClass.prototype = temp.prototype;
subClass.constructor = subClass;
subClass.typeName = subClassName;
subClass.baseClass = baseClass.prototype; // Shortcut to the prototype's methods
subClass.base = baseClass; // Cache the constructor
for(var index = 0; index < methods.items.length; index++) {
var resource = methods.items[index].getFunction();
var methodName = methods.items[index].getName();
if(methodName != "" && ! sti.objects.isDefined(subClass[methodName])) {
var method = sti.objects.createOverride(baseClassName, resource);
subClass[methodName] = method;
if(typeof subClass.prototype[methodName] == "undefined") {
subClass.prototype[methodName] = method;
}
}
}
}
Object.prototype.inherits = sti.objects.inherits;
Function.prototype.inherits = sti.objects.inherits;
function BaseClass() {
return {
A : function A() {return "A";}
};
}
function SubClass() {
inherits(BaseClass);
return {
B : function B() { return "B"; }
}
}
var b = new BaseClass();
var s = new SubClass();