2010-10-21 79 views
0

我试图在JavaScript中实现某种类的层次结构。 I 认为我理解了原型链,但我仍然必须理清构造函数链的 。继大卫·弗拉纳根的Definitive Guide, 我写JavaScript中的链接构造函数

function DerivedClass() 
{ 
    BaseClass.apply(this, arguments); // chain constructors 
    // do some initializations specific to DerivedClass... 
} 

var foo = new DerivedClass(); 

其中BaseClass()是用C写的我的本地函数++(我 使用QtScript)。我的问题是,那么,BaseClass()被称为 作为一个函数,而不是一个构造函数。

我可以编码BaseClass()始终表现为构造函数,但它调用 。但恐怕我的一些用户一天一个可能会忘记new 和只写

var bar = BaseClass(); 

在这种情况下,我想BaseClass()做一些更 不是初始化的全局对象明智的。例如:

if (!context->isCalledAsConstructor()) fail_gracefully(); 

但是然后构造函数链失败!

有没有办法链接构造函数并让BaseClass() 实际上被称为构造函数?或者我应该教育我的用户 永远不会忘记new?现在我很想通过更换上述 测试:

if (context->thisObject().strictlyEquals(engine->globalObject())) 
    fail_gracefully(); 

,但我不知道是否有处理这种更清洁的方式。

谢谢!

回答

0

回答自己...

我想到了我的问题过夜......我想我发现了一个有点 更令人满意的解决方案:表现为一个构造函数,如果this是卡莱的 实例。这个测试比检查 更严格一点,不管它是不是全局对象,但它仍然允许构造函数 链接,只要原型已被正确链接。

这里是我的家乡构造函数的第一行(SerialPort是我 基类,围绕QSerialDevice建):

/* 
* Should we behave as a constructor? 
* 
* We could use context->isCalledAsConstructor() to decide. However, 
* we may want to subclass SerialPort in JavaScript and chain the 
* constructors: 
* 
*  function DerivedClass() 
*  { 
*   SerialPort.apply(this, arguments); 
*   // do some more initializations... 
*  } 
* 
* This would fail if we decided on the basis of 
* context->isCalledAsConstructor(). The test below is somewhat less 
* strict. It allows constructor chaining provided the prototypes 
* have been properly chained. 
*/ 
bool behave_as_constructor = 
    context->thisObject().instanceOf(context->callee()); 

关于这个有趣的是:不像isCalledAsConstructor(),这 测试也可以实现在JavaScript构造函数中!

0

你应该教育你的用户永远不会忘记new

JavaScript中的所有“构造函数”毕竟都是函数,因此您无法防止构造函数被调用为函数。

这是不正确的JavaScript尝试和创建一个新的对象,而不使用new。仅仅因为没有像Java那样的“编译时间警告”,并没有改变它。

+0

嗯,从技术上讲,我可以通过抛出一个异常来保护它们,或者忽略'this'并返回一个全新的对象(比如'Array()')。我的问题是,第一个选项干扰构造函数链,而第二个选项与原型链不兼容。 – 2010-10-21 12:54:40