将OO语言编译为Javascript

时间:2012-10-27 20:10:39

标签: javascript oop compiler-construction

所以我是Javascript的新手,但我一直在研究一种与C#语义相似的编程语言,我想添加一个JS反编译器。我一直在寻找在Javascript中实现OOP的各种方法,但我不完全确定它是否会在下线工作。

让我先举一个例子。这是我的语言中非常简单的代码:

// test.fd
// this code will be put in package 'test'
class Foo
{
    float bar;

    - test
    {
        int x = 3;
    }
}

输出:

var test = {
    function Foo(){
        this.bar = 0.0;
    };

    foo.prototype.test = function(){
        var x = 3;
    };
}

现在我有一些问题。目前,当它编译类时,它会创建js函数'Foo()',我看到它实际上是一个构造函数。如果用户没有创建默认构造函数,我认为我应该默认创建它,在这种情况下使用它。但是如果我想在同一个类中拥有多个构造函数呢?它们是否必须具有不同的名称,我是否必须为每个构造函数重新创建所有方法和属性?

我的下一个问题是,在JS中实现继承的最佳方法是什么?我的语言假设所有方法都是虚拟的,所以它应该有希望使多态变得更容易。

全心全意,

1 个答案:

答案 0 :(得分:2)

正如@WaleedKhan指出的那样,你不应该为你不熟悉的语言构建一个反编译器。

首先,您编译的代码没有按照您的想法执行:

> var test = {
.    // Objects != namespaces
.    // Anything that is not a key: value pair is a syntax error.
.    function Test() {}
. }

SyntaxError: Unexpected identifier

如果你想要类似命名空间的效果,你应该使用函数,因为JavaScript does not have block scope

var test = (function(){
// This wrapper is an immediately invoked function expression (IIFE)
// It will act as a "namespace" inasmuch as functions and variables that are
// declared with `var` will not leak into the global scope.
// However, anything that you don't *explicitly* expose will be private.

function Foo() {
    this.bar = 0.0;
}

// JavaScript is case-sensative - foo != Foo.
Foo.prototype.test = function() {
    var x = 1;
};

return {
    Foo: Foo
};

})();

关于你的问题:

是的,Foo是一个构造函数(类似) - 但是,JavaScript不支持您想要执行的调度类型。相反,你需要一个包装器函数来调用相应的构造函数,具体取决于传入的参数:

function FooFactory() {
    if (typeof arguments[0] === "string") {
        return new FooString(arguments[0]);
    }
    else {
        return new FooObject(arguments[0]);
    }
}

很快就难以使用(尽管有some libraries可以更容易地进行此类调度)。

至于如何正确地做原型继承,你看过@ bobince对How to "properly" create a custom object in JavaScript?的回答

最后,您可能需要在JavaScript语言的How do JavaScript closures work?上查看excellent以及Kangax的articles trickier parts(他的ES5 compatibility table是不容错过。)

如果你做到这一点,祝你的冒险好运!