JavaScript++ Tutorial

The following is a quick tutorial for programmers to get you started with JavaScript++.

This tutorial assumes an understanding of computer science, class-based OOP, and JavaScript. The assumption of JavaScript knowledge does not translate to an assumption of knowing the C syntax, but rather assumes you know JavaScript and know about closures, scoping rules, prototypal inheritance, etc.

The Table of Contents looks huge, but if you're already familiar with the concepts, you should be able to breeze through this tutorial. Don't let the scrollbar deceive you; most of the HTML on this page is nested in <p> tags to make it easier on the eyes, and double spacing has a way of making texts seem longer.

NOTE: The syntax highlighting may be off as we wrote a quick regex highlighter instead of a real syntax highlighter.

NOTE #2: This is a terrible tutorial, and hopefully some JS ninjas out there that know how to use features like destructuring assignments can write a better tutorial ( that doesn't cover entire topics in two sentences :-) ) to help others.

Table of Contents

  1. Introduction
  2. Installation and Usage - Hello World
  3. Classes
    1. Constructors/Destructors, Anonymous Classes, First-class Citizens
    2. Instantiation, Instance Members, Static Members
    3. Nested Classes and Subclasses
    4. Singletons
  4. Block Scope
  5. Pluggable Type Systems, Type Safety, and Static Typing
  6. Regular Expressions
  7. Scoped Object Extensions
  8. Functional Programming
    1. Default Parameters
    2. args Array
    3. Function Overloading
    4. Expression Closures
    5. Higher Order Functions
    6. Rest Parameters
  9. Array Programming
    1. Ranges
    2. Array Comprehensions
    3. Array Operators
    4. Putting It All Together
  10. Miscellaneous
    1. Strings
    2. inside Keyword and for-inside Loops
    3. Existential Operator
    4. Logical Assignment Operators
    5. Exponent Operator
    6. Destructuring Assignments
    7. Switch Statements
  11. Debugging

Introduction

JavaScript++ is designed for fast and large-scale web development. It's designed to scale upwards and you can use it for its extended scripting capabilities (such as array comprehensions) which allow you to write small scripts in fewer lines, and, as your code base grows, JS++ will accomodate you with classes, type systems, and more.

JS++ is currently in very, very early alpha, and we released at least six months earlier than expected to coincide with Dart; although development began prior to Dart. With that said, your code will break. There will be bugs. You are almost guaranteed to run into a bug, and we do not recommend starting serious projects with it right now. However, we do want you to experiment, report bugs, contribute, and have fun!

All regular JavaScript should compile correctly in the JS++ compiler (even in the alpha). There are two features in regular JavaScript that JS++ "breaks:"

You don't have to learn all of JS++ in one go. Feel free to poke around; click only the links in the Table of Contents you are actually interested in learning. Remember, JS++ is just an extension of regular JavaScript; you can start writing regular JavaScript right now, and the JS++ compiler will compile it. You can pick and choose which language extensions you want to take advantage of so just click the relevant link when you want to learn it!

With that said, you don't need to write full blown applications or re-write your current applications in JS++. Keep working on your existing apps, and, when you stumble upon something which you feel can be expressed more easily with a JS++ feature, use it and let the JS++ compiler figure out the rest for you.

This tutorial is designed for programmers. We really don't get into the nitty gritty details on certain concepts, and, sometimes, we might just list the concept with a sample snippet and sentence illustrating how it works. If you're not familiar with the concept, look it up yourself or join our chat and we'd be happy to help.

Back to Top :: Back to Table of Contents

Installation and Usage - Hello World

It's very easy to get up and running with JavaScript++:

  1. Download the JavaScript++ compiler and files
  2. Open compiler.html in your favorite web browser
  3. Enter the following code in the "Source Code" textbox:

    let foo = "Hello World";
    alert(foo);

  4. Click "Compile."
  5. Click "Execute" to run the compiled code. You should get a dialog that says "Hello World"
  6. Copy the compiled code to a .js file and execute it in your browser or server.

For those that prefer the convenience of compiling through the command-line to avoid copying and pasting code:

  1. Install via npm

    sudo npm install javascript-plusplus -g

    Or if you're building from sources, go to the main directory and do:

    sudo npm install -g

  2. Example usages:

    js++ file1.jspp file2.jspp -o out.js # compile the two files and save to file out.js

    cat file1.jspp file2.jspp | js++ - > out.js # same thing, but with stdio pipes

Back to Top :: Back to Table of Contents

Classes

Classes in JavaScript++ are basically 1:1 with Java/C#. As a result, you can take most Java/C# classes off the internet, and translate them 1:1 to JavaScript++ by replacing int, string, and so on with var.

The class keyword is used to create a class. Classes are more flexible in JS++ than Java/C#, and JS++ differentiates between "class declarations" and "class expressions:"

class foo { //Class declaration
	private var bar = 1;
	protected var baz = 2;
}

var classExp = class { //Class expression
	public function Constructor() {
		return [100];
	}
};

new foo();
new classExp();

Constructors/Destructors, Anonymous Classes, First-class Citizens

Classes in JS++ are first-class citizens. You can pass them around, assign them to variables, etc.

You can also use JS++ classes in the same way you use self-executing JavaScript functions:

(class { //Anonymous class
	public function () { //Anonymous functions are treated as constructors
		return true;
	}
	
	public function Constructor(x) { //You can also type out "Constructor"
		return false;
	}
})();

As you can see in the above code, JS++ supports anonymous classes, and the syntax is extremely concise and intuitive compared to Java. Additionally, you'll notice anonymous functions inside a class are treated as constructors in JS++. This was a conscious effort to keep the syntax terse, but you can also write out "Constructor" (case-sensitive) to declare a constructor. Likewise, to declare a destructor, use the identifier "Destructor." There is no shorthand for destructors as they are less common.

Back to Top :: Back to Table of Contents

Instantiation, Instance Members, Static Members

JavaScript++ supports instantiation. There is no special syntax you need to figure out to determine if a member of a class is an instance member or a static member - it's exactly what you would expect if you're familiar with Java/C# OOP. To declare a static member, we simply use the "static" keyword:

class foo {
	//The following are instance members
	private var a = 1;
	public var b = 2;
	protected var c = 3;
	
	private function d() {}
	public function e() {}
	protected function f() {}
	
	//The following are static members
	public static var g = 1;
	static function h() { return 2; }
}

foo.g //1
foo.h //2
(new foo()).b //2

To instantiate in JS++, use the "new" keyword.

The beauty of JS++ classes is that there are no external dependencies. That means you can write your library or module in JS++ and fully utilize JS++ classes, compile it, and it will work in regular JavaScript seamlessly. All your instance members are still instance members, your static members are still static members, your private variables are still private, your public methods are still public, your constructor is still called on instantiation, your nested classes are still nested properly with the correct access modifiers, etc.

This is all completely seamless. Just compile your class to regular JavaScript, and a regular JavaScript user can start using your class like so:

new myClass(arg1, arg2, arg3);

Back to Top :: Back to Table of Contents

Nested Classes and Subclasses

JavaScript++ supports nested classes with exactly the type of syntax you'd expect in Java/C#:

class foo {
	class bar {
		private var baz = 100;
		public function() { //Constructor for bar
			return [baz];
		}
	}
	
	public function() { //Constructor for foo
		return new bar();
	}
}

new foo(); // [100]

Inside a class, you can only declare var, class, or function.

In the current alpha release, you can create subclasses using either the Java-style extends keyword or the C#-style colon:

class foo {
}

class bar extends foo {
}

class baz : foo {
}

The primary motivation for this is to provide choice and get feedback in the early alpha stage. If you prefer a certain syntax, please let us know! We're currently leaning towards the C# colon and thinking of cutting the Java "extends" as subclassing doesn't happen often, and when it does happen, you shouldn't need to type too much.

Back to Top :: Back to Table of Contents

Singletons

The singleton pattern in JS++ is extremely simple and concise compared to Java:

var foo = new class { //Singleton
};

(new class { //Anonymous singleton
})()

Back to Top :: Back to Table of Contents

Block Scope

JavaScript++ supports block scope through the let keyword:

var x = 1;

for (let i=0;i<100;i++) {
	console.log(i);
}

{
	let x = 2;
}

x; //1
i; //ReferenceError

For consistency and simplicity, let as implemented in JS++ is not exactly the same let as implemented by Mozilla. In JS++, there are only let statements and no let expressions.

Back to Top :: Back to Table of Contents

Pluggable Type Systems, Type Safety, and Static Typing

JavaScript++ implements the theory of "pluggable type systems" by Gilad Bracha. What Gilad's thesis does not cover is how pluggable type systems should be implemented in practice and admitted "more research" needed to be done in this area. We think we've done an excellent job implementing it in JS++.

The rationale for including pluggable type systems in JS++ is that one size does not fit all on the web: some want type inference, some want dynamic typing, some want strong typing, some want optional typing, etc.

The idea behind pluggable type systems is to turn the type system into a "plugin" for the compiler and let the user choose which type system he or she wants to use for a given file or project.

JS++ theoretically allows for all of the aforementioned type systems, and, by default, ships with a strong, static typing system called "strict." Here's how to use it:

#typesys strict //preprocessor directive

var a as String;

var b as Number = a; //TypeError, type mismatch

Note that preprocessor directives in JS++ must always be at the top of your source code or they will not be processed. This provides the power of a preprocessor without source code being littered with preprocessor directives all over the place that require you to manually hunt down.

With "strict," the compiler will perform static type checking and prevent silly errors that may occur from - for example - adding a string and number together:

#typesys strict

var a as String = 1 + "1"; //TypeError

In the above code, you'll need to explicitly convert the number to a string:

#typesys strict

var a as String = String(1) + "1"; //OK

Just remember in #typesys strict, strings can only be added (concatenated) to other strings. Any other operation will fail, and it doesn't allow some of the peculiar nuances in regular JavaScript such as subtracting strings.

Conversions can be done using the built-in constructor functions:

Additionally, when working with arrays, there are a few typed arrays as well:

When you use #typesys strict, you cannot declare a generic untyped array. Instead, you'll need to use one of the typed arrays above.

Most variable and function declarations will require an explicit type declaration as follows:

#typesys strict

var a as String = "foo";

function foo as String() {
	return "bar";
}

var b; //Error, must declare type

However, it's important to note #typesys strict will use type inference when dealing with objects in order to keep the syntax concise. You can declare a generic Object, and each property will have its type inferred like so:

#typesys strict

var o as Object = {
	foo: "foo", //inferred as String
	bar: 1, //inferred as Number
	baz: { //inferred as Object
	}
};

o.bar = String(1); //OK
o.foo = 1; //TypeError

Note that a type system cannot change the syntax. There is no syntax in JS++ that allows an explicit type declaration for each object property; we enforce this because it would be far too verbose otherwise. Therefore, it can be assumed all type systems in the future will also infer the types of object properties.

With arrays, we can also infer the type for a more terse syntax:

#typesys strict

var a as NumberArray = [1, 2, 3];

The type of the array is inferred based on the first element. For example, the following will fail:

#typesys strict

var a as NumberArray = ["1", 2, 3]; //TypeError, inferred as StringArray

However, we can take the above error and fix it with an explicit type cast:

#typesys strict

var a as Number[] = NumberArray(["1", 2, 3]);

a; //[1, 2, 3]

Notice how all the elements in array a are now of type Number. Also, notice how we used Number[] as a shorthand for NumberArray. Just remember you can't use Number[] for type casting and the shorthand is only available for the type declaration.

Although #typesys strict does not allow generic untyped arrays, sometimes we may want an array of arrays. #typesys strict allows this:

#typesys strict

var a as Array[] = ArrayArray( StringArray(), NumberArray() );

Just make sure all the arrays inside an array are typed arrays; otherwise, you'll get a TypeError.

The #typesys directive will search your typesys/ folder. To load a type system, input the filename and omit the ".js" extension. JS++ ships with "strict.js," so naturally the code is #typesys strict.

Back to Top :: Back to Table of Contents

Regular Expressions

NOTE: PCRE.js is NOT available in the current alpha.

JavaScript++ allows you to use custom regular expressions delimiters such as in Perl. This allows for much more readable regular expressions since, especially in web development, we may have to deal with URL's and other forms of data which may require lots of escaping. To use a custom regular expression delimiter, just prefix the regular expression with "m" and choose a character:

m@(https?)://www\.(javascript\.am)@i
/(https?):\/\/www\.(javascript\.am)/i;

JS++ also allows for "free spacing mode," also inspired by Perl, which ignores whitespace and comments. To use "free spacing mode," prefix the regular expression with "x." It can also be used in conjunction with custom regular expression delimiters:

mx@
(https?)://       #protocol
www\.             #www
(javascript\.am) #domain
@i
/(https?):\/\/www\.(javascript\.am)/i;

JavaScript++ also allows regular expression literals to be called as a function as seen in SpiderMonkey and v8. Adding a call to a regular expression literal will implicitly call the RegExp.prototype.exec method.

Back to Top :: Back to Table of Contents

Scoped Object Extensions

Before we get into functional and array programming, we need to explain "scoped object extensions."

Prototypal inheritance is incredibly powerful. We can use it to extend even the native global objects (Array, Number, etc.) and create extended methods which can then be called in a simple and elegant way:

Array.prototype.sum = function() {
	for (var i=0, len=this.length, sum = 0; i<len; i++) sum += +this[i] || 0;
	return sum;
};

[1, 2, 3, 4, 5].sum() //15

String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/gm, "");
};

"   foo   ".trim() //"foo"

This gives JavaScript amazing expressiveness, but almost everyone avoids extending the native global objects for fear of conflicts with libraries or others' codes.

In JavaScript++, you can extend the prototype of native global objects (or any object) and it will always be scoped to the nearest function or the global scope:

(function() {
	extension Array.prototype {
		sum: function() {
			for (var i=0, len=this.length, sum = 0; i<len; i++) sum += +this[i] || 0;
			return sum;
		}
	}

	[1, 2, 3, 4, 5].sum() //15
})();

Array.prototype.sum //undefined

With scoped object extensions, we can do some amazing things that aren't possible in other modern functional or array programming languages.

Back to Top :: Back to Table of Contents

Functional Programming

JavaScript++ doesn't do much to extend regular JavaScript's functional programming capabilities. Besides the lack of TCO, it's already pretty good. There are already solid functional programming libraries, and features such as currying may be implemented later.

Instead, JS++ aims to simplify functional programming. Are you using functional programming for Node.js and the like? Great! JS++ simplifies your code so you get more done in fewer lines.

Default Parameters

function add(a = 1, b = 1) {
    return a + b
}

add(3) //4
function add(a,b){
	a=a==null?1:a;
	b=b==null?1:b;
	
	var _bScope30={};
	
	return a+b;
}

add(3);

Back to Top :: Back to Table of Contents

args Array

JS++ exposes an args array. Unlike regular JavaScript, where the arguments object is an array-like object (and acknowledged as a bug in the language no less), JavaScript++ provides the args array to simplify your work.

The best part about the args array is that it will only appear in your compiled code if it gets used. The compiler is smart enough to not include it if you don't use it - resulting in faster code.

Back to Top :: Back to Table of Contents

Function Overloading

Function overloading is buggy in the current alpha and will not be covered in this tutorial. However, once it's fixed, it will share a similar function overloading syntax to C++, Java, and C#.

Back to Top :: Back to Table of Contents

Expression Closures

Expression closures allow you to omit the curly braces { ... } if your function is just one statement.

Derived from JavaScript 1.8 - but not precisely. Namely, JS++ prioritizes consistency over brevity; a terse syntax is still very high on our priorities list, but we won't compromise consistency because we want you to consult reference manuals less.

In JavaScript 1.8, you can omit the return keyword. For consistency with regular function declarations, JS++ requires the return keyword:

function add(a = 1, b = 1) return a + b;
function add(a,b){
	a=a==null?1:a;
	b=b==null?1:b;
	
	var _bScope33={};
	
	return a+b;
}

Back to Top :: Back to Table of Contents

Higher Order Functions

JavaScript++ comes equipped with all the ES5 higher-order array methods such as map and filter in its standard libraries so you can use them on any browser or host environment.

The relevant library is in lib/jspp/lang/es5.js. The current alpha doesn't support imports so you'll have to manually include it for the time being. Applications using the ES5 higher-order array methods now are guaranteed to be future proof though.

Back to Top :: Back to Table of Contents

Rest Parameters

Rest parameters allow us to retrieve the "rest" of the arguments.

For example, if a function foo has parameters a and b, and a variable number of remaining arguments, we can use rest parameters to simplify the code:

function foo(a, b, ...c) return c[0];

foo (1, 2, 3); //3
function foo(a,b,c){
	c = Array.prototype.slice.call(arguments,2);
	var _bScope40={};
	return c[0];
}

foo(1, 2, 3);

As you can observe, rest parameters use the ... operator, and they can only be the last parameter.

Back to Top :: Back to Table of Contents

Array Programming

Perhaps even less known than functional programming is the "array programming" paradigm. The core idea is to simplify operations on similar data, and consequently, we can express larger concepts and code more concisely. You've probably already been done array programming without even realizing it!

Ranges

Ranges can be used to quickly pre-populate an array with numbers or characters:

[1...5];
[5...1];
["a"..."f"];

var a = [x for (let x in ["a"..."f"])];
[1, 2, 3, 4, 5];
[5, 4, 3, 2, 1];
["a", "b", "c", "d", "e", "f"];

var a = (function(){var __TMP1__=[];for(var x in ["a","b","c","d","e","f"]){__TMP1__.push(x)}return __TMP1__})();

JS++ ranges are inspired by Haskell, so we may later implement [3, 6...20] as you would expect from Haskell.

Back to Top :: Back to Table of Contents

Array Comprehensions

If you've used Python, an array comprehension is the same as a "list comprehension." If you haven't used Python, the basic premise is that you can create an array and programatically pre-populate it with values - usually from an existing array, range, object, or list-like structure.

It's an incredibly useful shorthand. For example, if we're in a DOM host environment, we can get all the properties of the screen object like so:

var screenProps = [x for (let x in screen)];
var screenProps=(function(){var __TMP1__=[];for(var x in screen){__TMP1__.push(x)}return __TMP1__})();

It will only work inside an array initializer [ ... ].

The first part of an array comprehension should be an expression. This is the expression that will be used to calculate each array element's value. In the above example, our expression was just a variable identifier: x. Next, we have the loop. We need a loop so we know how many elements should be created. In the sample code, the loop is: for (let x in screen); this will loop over the screen host object and each property will be assigned to x. If we don't want to look up every property in the prototype chain, we can use a for-inside loop (discussed later).

We can also use ranges and conditionals to pre-populate an array with every number in that range squared but only if the original number is greater than 5:

var squared = [x * x for (let x in [1...10]) if (x > 5)];
(function(){var __TMP1__=[];var squared=for(var x in [1,2,3,4,5,6,7,8,9,10]){if(x>5){__TMP1__.push(x*x)}}return __TMP1__})();

JS++ also supports nested array comprehensions and an infinite number of for-in/for-inside loops and conditionals.

Back to Top :: Back to Table of Contents

Array Operators

Array operators allow us to quickly perform operations on arrays with a terse syntax. For example, here's how to multiply each element in a range by 5:

[1...10] *= 5;
(function(){for(var i=0,a=[1,2,3,4,5,6,7,8,9,10],l=a.length;i<l;i++){a[i]=a[i]*5;}return a})();

Back to Top :: Back to Table of Contents

Putting It All Together

This is meant to be a lightweight tutorial so now that we've introduced some array programming concepts and scoped object extensions, here's some sample code to get your brain flowing as to how array programming can be combined with scoped object extensions and how powerful and simple JS++ becomes with such features:

import jspp.lang;

(function() {
	//Extend Array.prototype - but keep it in this scope
	extension Array.prototype {
		//Split first and last x elements
		analyze: function(x as Number) {
			return { original: this, split: this.slice(x, -x) };
		}
	}
	
	while (true) {
		//Create an array of arbitrary length and fill it with an array comprehension
		var x = [i for (let i inside Array(+readline() || 0)];
		
		x.analyze(1); //Calls Array.prototype.analyze - which is scoped
	}
	
	//The Standard Library also allows us to perform a regex search on data inside an array
	["foo", "foobar", "bar", "foo bar", "baz"].search(/^foo/i).analyze(1);
	
	//Ranges, array comprehensions, and the Standard Library's Array.prototype.sum all in one
	[i for (let i inside [1...10])].sum(); //55
})()

print(Array.prototype.analyze); //undefined

The above code uses SpiderMonkey's readline() and print(), and the import statement won't execute in the current alpha, but it should get you thinking.

Back to Top :: Back to Table of Contents

Miscellaneous

Strings

JavaScript++ supports multi-line strings with a syntax similar to Python's:

var a = """foo
		    bar""";

Spacing in multi-line strings is determined by the first line. In the example above, since the first line is not prefixed by any tabs or spaces, all the following lines will have whitespace removed from the beginning. If the first line was prefixed with one space, all subsequent lines will be prefixed with one space, and so on.

You can also use the above syntax to avoid having to escape quotes in your strings for better readability.

Subsequent releases of JS++ will include string interpolation via the Standard Library and heredocs for use cases such as multi-line HTML.

Back to Top :: Back to Table of Contents

inside Keyword and for-inside Loops

Often, you'll want to check if an object has a property, but you don't want to look up the prototype chain. JavaScript++ provides the inside keyword which is a shorthand for Object.prototype.hasOwnProperty.call - it's safe and concise and won't fail if you check if an object has a property called "hasOwnProperty."

Furthermore, it's extremely tedious to loop over an object's own properties instead of the object's properties plus all the properties it inherited. The for-inside loop solves that:

foo inside bar;

for (let i inside foo) console.log(i);
Object.prototype.hasOwnProperty.call(bar, foo);

var _bScopeStmt1={};_bScopeStmt1.a=undefined;for(_bScopeStmt1.a in __TMP1__=foo)if(Object.prototype.hasOwnProperty.call(__TMP1__,_bScopeStmt1.a)){console.log(_bScopeStmt1.a);}_bScopeStmt1=null;}

The inside keyword and for-inside loop brings us a little closer to associative arrays/dictionaries in JavaScript, and JS++ may bring a full dictionary implementation in the future.

Back to Top :: Back to Table of Contents

Existential Operator

It's often tedious to check for the existance of a variable or object property. JavaScript++ makes it easy:

var foo = ?widget ? bar : baz;

foo ?= 1;
var foo = (typeof widget!='undefined' && widget!==null) ? bar : baz;

foo = foo==null ? 1 : foo;

Back to Top :: Back to Table of Contents

Logical Assignment Operators

JS++ supports the logical assignment operators &&= and ||=:

foo &&= bar;
bar ||= baz;
foo = foo && bar;
bar = bar || baz;

Back to Top :: Back to Table of Contents

Exponent Operator

JavaScript++ supports an exponent operator:

5 ** 5;
foo **= bar;
3125;
foo = Math.pow(foo, bar);

As you can see from the compiled code, JS++ is smart enough to replace your code with a constant where appropriate instead of calling the Math.pow function for faster execution.

Back to Top :: Back to Table of Contents

Destructuring Assignments

Destructuring assignments can be used to break up an array and assign them to variables.

In its most basic form, it can be used to swap variable values, for example: [a, b] = [b, a]

More complex cases may involve using destructuring assignments with regular expressions to create more readable code and get more done in fewer lines:

var [, protocol, domain] = m@(https?)://www\.(javascript\.am)@i.exec("http://www.javascript.am");

console.log(protocol); // http
console.log(domain); // javascript.am
(function(global){var _bScope33={};var __TMP1__=/(https?):\/\/www\.(javascript\.am)/i.exec("http://www.javascript.am");var protocol=__TMP1__[1],domain=__TMP1__[2];
console.log(protocol);console.log(domain);}).call({},this);

Back to Top :: Back to Table of Contents

Switch Statements

Switch statements support multiple case values (separated by a comma) like so:

switch (foo) {
	case true, 1:
		return true;
	case false, 0, "", undefined, null:
		return false;
}

Additionally, the break statement will be automatically included at the end of each case statement for much more convenience compared to the classic C-style switch statements found in regular JavaScript.

Back to Top :: Back to Table of Contents

Debugging

JavaScript++ can be compiled in "debug mode" which produces code with source mappings.

Debug mode is enabled by default.

For example:

class foo {
	public function Constructor() {
		console.log(foo); //ReferenceError
	}
}
//@line 1
(function(global){var _bScope10={};function foo(){var __SUPER__;return ((function(){var __CLASS8__=this,__PDEFINE__={}.constructor.defineProperty,__NOENUM__={enumerable:false};if(typeof __PDEFINE__!='function')__PDEFINE__=null;this.__SUPER__=__SUPER__;__PDEFINE__&&__PDEFINE__(this,'__SUPER__',__NOENUM__);this.__PROTECTED__={};__PDEFINE__&&__PDEFINE__(this,'__PROTECTED__',__NOENUM__);this.Constructor=function(){
//@line 2
var _bScope6={};
//@line 3
console.log(foo);return __CLASS8__};__PDEFINE__&&__PDEFINE__(this,'Constructor',__NOENUM__);return this}).call({})).Constructor.apply(this,[].slice.call(arguments))}}).call({},this);

It should be noted this feature was designed primarily for debuggers. We hope to include more advanced debugging features in the future such as compiling with symbol tables.

If you're debugging manually: in the above code, once you hit a ReferenceError since "foo" was not declared, you can easily use your favorite debugging tool such as Firebug or WebKit Inspector to discover the source of the problem - and the corresponding JavaScript++ line number is just one line above in a comment.

The source mappings are compatible with Mozilla SpiderMonkey with the JSOPTION_ATLINE option. It should be built into future versions of Firefox by default.

On Debian systems (and also on Ubuntu), you can install SpiderMonkey from the package "spidermonkey-bin:"

$ sudo apt-get install spidermonkey-bin
$ js
js> options("atline")

js> try{ eval("//@line 500\nfoo") }catch(e){ print(e.lineNumber) }
500

Notice how the error line number in the above code produces "500."

We are hoping in the future, more browsers will ship with features for debugging with source maps by default. To our knowledge, WebKit and Mozilla are working to standardize this at the moment.

Additionally, the JavaScript++ command-line compiler will provide a visualization for all compile-time errors. For example, notice the improper use of the ... operator below:

Notice how the JavaScript++ compiler provides visual indicators for the exact line and character where the error occurs. This helps tremendously when debugging and speeds up development time.

Back to Top :: Back to Table of Contents

 

JavaScript++ is under re-development and will be coming back! Get instant notification when it returns by clicking here.