!!! JavaScript

The JavaScript language is a general purpose language that is most often, but not necessarily, run within an Internet browser.  Except for the name, JavaScript is completely unrelated to Java.

!! The Language

All symbols in JavaScript are case-sensitive.

! Data types

| String | 'Hello' (prefer this form)
|        | "Hello" 
| Number | 45
|        | 3.14
| Boolean | true/false
| null | null
| undefined | undefined
| NaN | not a number
| RegExp | /.*/g
| Object (JSON) | {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}
| Array | {{{[33, 'Dog', 55.6]}}}


All numbers are floating point using a format that exactly represents integers (no rounding error for integers).

There is no character type.

Strings are represented with double-quotes OR single-quotes, and characters can be escaped with a backslash.

You can Concatenate strings with +, i.e.:

{{{"abc" + "def"}}}


! Boolean values and null

Two constants "true" and "false"

Result of comparisons, i.e.:

{{{x == y}}}

false, null, undefined, NaN, 0, and "" are all treated as "false".  Anything else is treated as "true".

The {{{===}}} operator is used to tell if the two arguments are the same object (not just equal).

! Variables

Variable names must start with a letter, underscore, or $, and may contain all of those characters plus numbers thereafter.

Variables are type-less.  You can assign a number, string, etc. to any variable at any time.

Declare with "var" like this:

{{{var a;
var b = 44;
var c = 'hello';
var d, e=7, f;}}}

Be very careful!  Most JavaScript's will allow you to assign a value to an undeclared variable.  It will seem to work but you have unknowingly created a GLOBAL variable rather than one local to the function you are in.  ALWAYS declare variables!

Variables are either global or local to the function in which they are declared.  This means if you declare it outside of a function, it is global.  If you declare it inside a function it is local to that function.  Keep all variables as local as possible.  {} blocks do not establish a variable context / scope in JavaScript.


! Functions

There are two ways of declaring a function as follows ("function" is a keyword):

{{{function myFunc(x, y) {
	return x + y;
}
}}}

The above is pretty traditional.  Notice that none of the variables have types.  Elsewhere, you can call the above function in an expected way, i.e.:

{{{myFunc(3, 4);}}}

Or, to use the return value:

{{{var r = myFunc(3, 4);}}}

Another way to create a function is through a variable syntax.  Although you may think "what good is that?", it is extremely important, and it opens the door to some very, very important things.  The above function can also be defined as follows:

{{{var myFunc = function(x, y) {
	return x + y;
}
}}}

This makes the following about JavaScript clear:

1.  All functions in JavaScript are just variables holding function values!

2.  Function values can be passed around and assigned just like variables, i.e.:

{{{function abc(x, y) {
	return x + y;
}

var def = function(x, y) {
	return x * y;
}

print(abc(3, 4));
print(def(3, 4));

var g = abc;
var h = def;

print(g(4, 5));
print(h(4, 5));
}}}

So, it doesn't matter which way you declare the function, it is the same.  The value of declaring it as a variable, however, is to make it clear what is really is - a variable!

Inside function are all of the standard stuff like "if", "else", "while", "do", "for", "return", "switch", "continue", "break", "throw", "try/catch", "with", etc..


! Arrays

Arrays in JavaScript are zero based indexing.

{{{var myArray = [36, 45, 'hello'];

print(myArray[0]);
print(myArray[1]);
print(myArray[2]);

myArray[1] = 'dog';

print(myArray[0]);
print(myArray[1]);
print(myArray[2]);

print(myArray.length);

// You can auto-extend an array:

myArray[3] = 'new element';

print(myArray[3]);
print(myArray.length);

myArray[43] = 'far away';
print(myArray[43]);
print(myArray.length);  // returns 44}}}


! Objects

Objects are really hash tables!


{{{var x = new Object();

x['George'] = 44;  // key=George, value=44
x['sam'] = 27;
x['marry'] = 33;

print(x['George']);
print(x['sam']);

// alternate way of doing the same thing

var x = new Object();

x.George = 55;  
x.sam = 66;
x.marry = 77;

print(x.George);
print(x.sam);

// you can even assign them one way and access them in the other


print(x['George']);
print(x['sam']);

print(Object.keys(x).length);  // the number of elements

// Enumerating through all the keys

for (var k in x)
    print(k);


// Enumerating through all the values

for (k in x)
    print(x[k]);


// A very important way of initializing an object:

var y = { abc: 104, def: 5.5, hij: 'hello' };

print(y["abc"]);
print(y.def);
print(y.hij);
}}}

!! Classes

{{{
function MyClass(init) {
    this.iv1 = init;
    this.iv2 = 0;
}

MyClass.cv1 = 101;

MyClass.getCV1 = function() {
    return MyClass.cv1;
}

MyClass.setCV1 = function(val) {
    MyClass.cv1 = val;
}

MyClass.prototype.getIV1 = function() {
	return this.iv1;
}

MyClass.prototype.setIV1 = function(val) {
	this.iv1 = val;
}


var x = new MyClass(36);
var y = new MyClass(42);

print(x.getIV1());
print(y.getIV1());
print(MyClass.cv1);

x.setIV1(44);
y.setIV1(22);
MyClass.setCV1(202);

print(x.getIV1());
print(y.getIV1());
print(MyClass.getCV1());
}}}



!  Inheritance

{{{
function Mammal(name) {
    this.name = name;
}

Mammal.prototype.getName = function() {
    return this.name;
}

function Cat(name, color) {
    Mammal.call(this, name);   //  call the super constructor to inherit its instance vars
    this.color = color;
}

Cat.prototype = Object.create(Mammal.prototype);  //  copy parent prototype to
						  //  inherit its methods
						  //  this must be done before
						  //  assigning local methods

Cat.prototype.getColor = function() {
    return this.color;
}

var a = new Cat("Woolfy", "Brown");

print(a.getName());
print(a.getColor());

}}}