代码之家  ›  专栏  ›  技术社区  ›  Edgar Bonet

在JavaScript中链接构造函数

  •  0
  • Edgar Bonet  · 技术社区  · 14 年前

    我试图在JavaScript中实现某种类层次结构。我 构造函数链接。跟随大卫·弗拉纳根 Definitive Guide , 我写的

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

    哪里 BaseClass() 是用C++编写的地雷函数(我是 QtScript ). 我的问题是, 基类() 被称为 作为函数,而不是构造函数。

    我可以编码 基类() 被称为。但我担心有一天我的一个用户会忘记 new 然后就写

    var bar = BaseClass();
    

    在这种情况下,我想 做更多的事

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

    但是构造函数链接失败了!

    基类() 实际上被称为构造函数?或者我应该教育我的用户 永不忘记 新的 ? 现在我想替换上面的测试

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

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

    谢谢!

    2 回复  |  直到 14 年前
        1
  •  0
  •   EMMERICH    14 年前

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

    毕竟,JavaScript中的所有“构造函数”都只是函数,所以不能防止构造函数被调用为函数。

    新的 . 仅仅因为没有Java中的“编译时警告”,就没有什么不同。

        2
  •  0
  •   Edgar Bonet    14 年前

    我一夜之间想到了我的问题。。。我想我发现 更令人满意的解决方案:如果 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构造器中实现!