0

So I'm new to Javascript, but I've been working on a programming language with similar semantics to C#, and I want to add a JS trans-compiler. I've been looking through various ways of achieving OOP in Javascript, but I'm not entirely sure if it's going to work further down the line.

Let me start with an example. Here's a very simple bit of code in my language:

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

    - test
    {
        int x = 3;
    }
}

It outputs this:

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

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

Now I have a few of questions. Currently, when it compiles the class it creates the js function 'Foo()', which I see is really behaving as a constructor. I'm thinking I should create this by default if the user doesn't create a default constructor, in which case it is used. But what if I wanted to have multiple constructors for the same class? Will they have to have different names, and will I have to recreate all methods and properties for each constructor?

My next question is, what is the best way to achieve inheritance in JS? My language assumes all methods are virtual so it should hopefully make polymorphism easier.

Thanks all,

  • 1
    The output doesn't seem like valid Javascript to me. – Waleed Khan Oct 27 '12 at 20:12
  • 3
    Just as an aside, have you seen http://www.typescriptlang.org/ yet? – ryan Oct 27 '12 at 20:12
  • I haven't ryan, I'll check it out. Thanks Waleed, I haven't actually got round to executing the code as there is no entry point and no commands yet to run! It's in very early stages (as is my knowledge of javascript). I'm concerned about the syntax of the 'test' namespace – user1779891 Oct 27 '12 at 20:14
  • 2
    Look at [CoffeeScript](http://coffeescript.org/), they do basically what you're trying to achieve, the implementation is open source, and they try to make the compilation output as straightforward as possible. – millimoose Oct 27 '12 at 20:15
  • Possible duplicates: Overloading at http://stackoverflow.com/a/457589/794234, and inheritance at http://stackoverflow.com/a/7487065/794234 – just.another.programmer Oct 27 '12 at 20:17
  • 2
    @user1779891 One does not build a transcompiler for a language they don't well. – Waleed Khan Oct 27 '12 at 20:18
  • Also consider [GWT](https://developers.google.com/web-toolkit/) or [PyJS](http://pyjs.org/) – Alastair McCormack Oct 27 '12 at 20:59
  • 1
    You might also want to look up [emscripten](https://github.com/kripken/emscripten/wiki). – Spudley Oct 27 '12 at 21:02

1 Answers1

2

As @WaleedKhan points out, you shouldn't build a transcompiler for a language you don't know well.

First off, your compiled code does not do what you think it does:

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

SyntaxError: Unexpected identifier

If you want a namespace-like effect you should use functions, since 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
};

})();

As to your questions:

Yes, Foo is a constructor (of a sort) - however, JavaScript does not support the kind of dispatch you want to do. Instead, you'd need a wrapper function that calls the appropriate constructor depending on the arguments passed in:

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

That rapidly gets difficult to work with (though there are some libraries that make it easier to do such dispatching).

As for how to properly do prototype inheritence, have you seen @bobince's answer to How to "properly" create a custom object in JavaScript?

Finally, you may want to take a look at How do JavaScript closures work? as well as Kangax's excellent articles on trickier parts of the JavaScript language (his ES5 compatibility table is not to be missed either).

If you made it this far, good luck on your adventure!

Community
  • 1
  • 1
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293