JavaScriptEngine: List of Missing Functionality

I understand that the JavaScriptEngine's documentation explicitly states that it's not fully standards-compliant, but I noticed many things were missing when trying to play around with it.

Certainly, some of these things are easier to implement than others! And it also seems that a JS unit test would be handy if it ever starts moving forwards to compliancy...

In any case, even though I've no idea what the plans are for the engine (or where it's at as per the upcoming JUCE, v4), here's a list of missing functionality:

Mistakes - the intepreter is a tad too lenient! (http://www.w3schools.com/js/js_mistakes.asp) 

  • This array definition shouldn't be supported/should be an error: "var points = [40, 100, 1, 5, 25, 10,];"
    <ul>
    	<li>The array definition ends with a comma, which fails or behaves unexpectedly in some interpreters</li>
    </ul>
    </li>
    <li><span>This object definition&nbsp;shouldn't be supported/should be an error:: "var&nbsp;</span>person = {firstName:"John", lastName:"Doe", age:46,}"
    <ul>
    	<li><span>The&nbsp;</span><span>object definition ends with a comma, which fails or behaves unexpectedly in some interpreters</span></li>
    </ul>
    </li>
    

Keywords (http://www.w3schools.com/js/js_reserved.asp)

  • finally (http://www.w3schools.com/jsref/jsref_try_catch.asp)
  • const (http://www.w3resource.com/javascript/statements/const.php)
  • switch statements (http://www.w3schools.com/jsref/jsref_switch.asp)

Array Bugs

//Testing this using the JUCE Demo
​var person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46;
var x = person.length;
var y = person[0];

Demo.print(x); //Should expect 0, but we get 1
Demo.print(y); //Should expect 'undefined' but we get 46

See: http://www.w3schools.com/js/js_mistakes.asp and its browser demo http://www.w3schools.com/js/tryit.asp?filename=tryjs_array_associative_2

Operators (http://www.w3schools.com/jsref/jsref_operators.asp)

  • NOT bitwise operator (ie: ~) 
  • typeof operator (https://github.com/julianstorer/JUCE/commit/190a9850039411742435c4a1a5059df237d329b1)
  • new operator
  • delete operator
  • in operator
  • instanceof operator

Objects

  • Date object (http://www.w3schools.com/jsref/jsref_obj_date.asp)
  • String object, and global functions (http://www.w3schools.com/js/js_strings.asp)

Math Constants (http://www.w3schools.com/js/js_math.asp)

  • SQRT2
  • SQRT1_2
  • LN2
  • LN10
  • LOG2E
  • LOG10E

(If you see this post at a future date, it's because I'm updating it as I see changes coming in)

Another thing missing is the ability to create closures.

Creating a closure looks like this:

function greeter(whatToGreet)
{
    return function() { Demo.print("hello " + whatToGreet + "!"); };
}

var g1 = greeter("world");
var g2 = greeter("sea");

g1();
g2();

This code should print out

Hello world!
Hello sea!

Executing the greeter function creates a closure. It returns a reference to the nested function, and this function can still access the local variable whatToGreet from the greeter function.

This access is by reference. Consider the following:

var ourCallbacks = [];

function setOurCallbacks()
{
    for (var index = 0; index < 3; ++index)
    {
        ourCallbacks[index] = function() { Demo.print("Iteration " + index); };
    }
}

setOurCallbacks();

for (var i = 0; i < 3; ++i) ourCallbacks[i]();

This is a failed attempt to make a series of callbacks working with some index. There is one local variable called index in
setPrintFunctions, which has the value 3 when that function ends. All 3 closures will access the same copy of that variable because there's only 1 function call. So it will print

Iteration 3
Iteration 3
Iteration 3

I don't know if it's worth the effort to implement this in the JavaScriptEngine, but from my experience with using JavaScript in browsers, closures are pretty fundamental when doing anything non-trivial involving callbacks.

--
Roeland

Writing Javascript daily at work in the context of Node.js, callbacks and closures are quite a fundamental part of JS code. But I do also realise that the JUCE javascript engine is intentionally not fully formed. I imagine it would take a lot of work to get a full implementation as part of JUCE.

It would make much more sense to integrate the Chrome V8 engine in a project if you need a full JS implementation. 

Thanks guys - we'll certainly put this stuff in the backlog, and some of it's easy to add.

Closures may or may not be easy - it may be a one-line fix, but the hard bit is figuring out exactly what would need to change!