0

我正在尝试在 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();

但我想知道是否有更清洁的方法来处理这个问题。

谢谢!

4

2 回答 2

0

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

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

尝试创建新对象而不使用new. 仅仅因为没有像 Java 那样的“编译时警告”,并没有什么不同。

于 2010-10-21T12:40:04.323 回答
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 构造函数中实现!

于 2010-10-22T12:29:40.933 回答