= Basic Javascript Reference =
=== Data Types & Variables ===
* Core JS datatypes: **number** (no distinction between float and integer), **string** (variable length, but immutable), **boolean**, **object**. Also //null// and //undefined// are special trivial data types.
* An object is a 'composite' datatype, consisting of numbers, booleans, strings and other objects. There are a number of special types of objects in JS, including [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Function|functions]] and [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array|arrays]].
* Since functions are objects, [[#functions|they can be passed]] just like any other datatype.
* Javascript 1.5 doesn't have real classes, but [[#classes|objects can kind of simulate]] the behavior. JS 2.0 will supposedly rectify this.
* There are also a bunch of random built-in objects, like [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Math|Math]], [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date|Date]] and [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:RegExp|RegExp]].
* Even the primitive datatypes have object representations: [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Number|Number]], [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:String|String]] and [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Boolean|Boolean]]. But for the most part, conversion between these is transparent, so you don't need to worry about it.
* //null//, as with other languages, is a special value (actually an object in JS) that means no value. (That said, its not like SQL as it converts to 0 if typecast to a number, 'null' for a string, and false for a boolean.)
* //undefined// is a special value that means 'unassigned', e.g. a variable was created, but never assigned a value. Note how that is different from //null//, which means a variable has been specifically assigned no value. In practice, //null// is the only one of those two you'll assign to anything. //undefined// is really only used for testing purposes, e.g.: if (myVar === undefined) { doSomething(); }
* Subtle, but important: having a variable be declared but undefined is different than having a variable that was never declared at all (and thus is 'undefined'). The former is fine; the latter throws an error:
var myVar1; // myVar1 is declared, and has a value of undefined
myVar2 + 3; // myVar2 isn't even declared; this will throw an error
* As with other languages, primitive data types are passed by value, and objects are passed by reference.
* Strings are immutable in JS, which means they can't be changed at all. This is highly annoying, because it means you can't do string substitution like you can in PHP:
$myString = "Hello {$name}, you have an {$animal}." // PHP string sub, not valid in JS
* JavaScript is untyped, and you can easily reassign any variable to any type of data:
var myVar = 9;
myVar = 'someString';
myVar = new Object();
* Scope is local to a function, but //not// local to a ''{}'' block like Java. JS has no block scope.
* You should **always** declare variables with ''var''. (Technically, you can assign a variable a value and it will be implictly declared, but these are always declared as globals, so a better idea is just to always declare them yourself with ''var'').
=== Operators & Statements ===
* JavaScript has all the standard operators that most languages do; e.g. +, -, ++, <, >, && etc. etc. Precedence and associativity (e.g. use inside of parens) is pretty much as you'd expect
* Like many other languages, JS supports that //identity// operator, ===. It lets you compare two variables to see if the values/objects they contain are 'identical'. This means that they are either the same primitive value, or the exact same object in memory (Thus two objects that have all the same values but are a copy of each other are //not// identical). == typecasts, but === does not, so '' '3' !== 3''.
* ''instanceof'' and ''typeof'' are also operators in JavaScript. They do similar things:
* ''instanceof'' is used to figure out whether a given object is a certain type of object, e.g. ''a instanceof Array'' would return true if a is an array. It requires both left and right-side operands.
* ''typeof'' takes only a single (right-side) operand (e.g. ''typeof a''), and returns a string with the type of object. Unfortunately, it only returns base types... 'number', 'string', 'boolean', 'object', 'function' or 'undefined'. NOTE: functions are objects in JS, so I'm unclear on why it wants to return a special value for function, but it does.
* As with other languages, JavaScript supports the conditional operator: ''?:'', e.g. (x > 0) ? document.write('x is positive') : document.write('x is negative');
* ''new'' and ''delete'' are for creating new objects and deleting them. Since JavaScript doesn't really have classes, you can't create and delete classes, but [[#classes|objects are kinda like classes]].
* JavaScript has all the standard statements you'd expect from any decent language, e.g. ''if/else'', ''while'' and ''do...while'', ''for'' loops, etc. It also has a few funny ones:
* ''for...in'' can be used to iterate over the properties of an object. It is used like this:
var myObj = new Object();
myObj.prop1 = 3;
myObj.prop2 = 4;
for (var index in myObj) {
document.write(index+',');
}
That will produce the output ''prop1,prop2,'' . Note that it is actually iterating over the property names themselves... if you want to get the value of the property, you need to look it up using the array notation: ''document.write(myObj[index])''.
* JavaScript supports decent exception handling... with ''throw'' and ''try/catch/finally''. These are the same as in other languages, but it's definitely nice that it has ''finally'', which is guaranteed to execute after the other statements.
=== Objects ===
* Objects are the core structure in JavaScript. They are used to represent arrays, [[#classes|classes]] (somewhat poorly), [[#namespaces|namespaces]], [[#functions|functions]], and just about anything else you can think of.
* An object consists of some number of 'properties' (e.g. variables). A property can be a primitive type (number, string or boolean), or another object.
* Properties can be accessed via dot notation (''myObj.prop1'') or via array notation (''myObj["prop1"]'').
* The latter is useful in ''for...in'' loops, and if you have to access a property with a name that contains otherwise invalid identifier characters. See [[Using PHP Input Arrays with Javascript]] for an example.
* Objects must be declared with either curly bracket syntax (''var foo = {};'') or the ''new'' syntax (''var foo = new Object();'')
* Every object has a 'prototype' property, which is where you can put variables (including other objects or functions) that will be shared with all copies of that type of object. For example, if you want to add a trim function onto the String object, you'd say:
String.prototype.trim=function(){
return this.replace(/^\s*|\s*$/g,'');
};
=== Arrays ===
* Objects are used to represent arrays. To make life easier, JS gives you some simple functionality that let you manipulate arrays.
* ''myArray.length'' gives you the length of your array. Something that's rather cool: you can set the length property if you want, and it will create an array of that size. So if you say ''myArray.length = 10000;'', you'll have an array of 10,000 elements.
* ''join()'', ''reverse()'', ''sort()'' and several other functions are available as well.
* Unlike PHP, JS **only supports numerically indexed arrays**. You can simulate associative arrays using objects, and creating a new property for each 'key' in the array, but then most of the array functionality (e.g. the ''length'' property) won't work. See [[Associative Arrays in JavaScript]]
=== Functions ===
* Functions are **really** cool in Javascript. In most languages, they are just a syntactical feature of the language. In JS, **functions are first-class objects**. This means we can treat a function just like any other piece of data, and can do all kinds of nifty things that we can't do in other languages.
* Nest a function inside another function
function hypotenuse(a,b) {
function square (x) { return x*x}
return Math.sqrt(square(a), square(b))
}
// square() can't be accessed here, because it was defined in the hypotenuse()
// function and thus isn't global in scope
* Use a Function() constructor. You can create a function just like any other object; using a constructor.
var addNumbers = new Function('x', 'y', 'return x+y');
document.write(addNumbers(4,5)); // returns 9
This is mainly useful in dynamically creating functions (during code execution); otherwise you may as well just use the ''function'' statement.
* Pass a function as an argument, just like we can pass any other object:
var addNumbers = function (a, b) { return a + b; } // define a function and assign it to a variable
function doMath(mathFunc, a, b) { // create a function that accepts an argument
return mathFunc(a,b);
}
doMath(addNumbers,2,3); // call the function with the argument
* Create anonymous functions. You create anonymous variables and objects all the time... for example, if you said:
document.write ('foobar');
then an anonymous variable is created for the string 'foobar'. You can do the same with functions:
// this defines an anonymous function with a and b as the arguments, and then
// executes that function with 3 and 4 as the values
document.write(function(a, b) { return a+b; }(3,4));
* Since functions are variables, you can assign them as properties of objects. These are called ''methods''. Methods have one important core difference that makes them more than just 'functions attached to objects'. You can access the parent object with the ''this'' keyword inside the method that it is called from. For example:
var myObject = {};
myObject.a = 5;
myObject.b = 7;
myObject.goo = function () {return this.a + this.b};
document.write(myObject.goo())
=== Classes ===
* Objects are used to represent classes in JavaScript, but the implementation is confusing and incomplete at best.
* Objects aren't true classes, like in PHP5, Java or C++. They can't have private or protected members (well, [[http://w3net.eu/code/privateMembers/|not easily]], anyway)
* Because of the lack of true class support, I tend to shy away from object oriented programming in Javascript. I do [[namespacing and aliasing namespaces in javascript|namespace everything]], but I don't generally make and instantiate objects.
* To create a 'class', you create a special constructor function:
function Circle(r) {
this.radius = r;
}
By convention, class names always start with a Capital Letter. That's how you tell them apart from normal functions. //this// refers to the object you're creating, so setting ''this.radius'' means you create and set a public member ''radius''. It's an instance member (or 'instance property', in JS terms), which means it will be different for every instance of the class that you instantiate.
* Note that you **must** use the function statement to make a class object. If you init an object via literal notation, e.g. ''var Rectangle = {}'' then you CAN'T instantiate it. Thus the literal notation is generally more useful for namespacing than classes.
* To declare an instance method, you can either use the ''prototype'' object, or you can put the methods inside the constructor:
// Option #1: This is the better way to do it, because it stores one copy of the method,
// rather than a copy for each object that is instantiated.
function Circle(r) {
this.radius = r;
}
Circle.prototype.diameter = function () {
return 2 * this.radius * 3.14;
}
// Option #2: here, we get identical copies of the function every time we
// create a new Circle object. That uses a lot of memory.
function Circle(r) {
this.radius = r;
this.diameter = function () {
return 2 * this.radius * 3.14;
}
}
* Javascript also supports assigning //class properties// and //class methods//. These are just assigned like any other property of any object. Note that you can't use the ''this'' keyword in these.
function Circle(r) {
this.radius = r;
}
// class property. ALL CAPS is a convention, much like defining constants in PHP, Java, etc.
Circle.MAX_RADUIS = 2;
// class method.
Circle.isTooBig = function(radius) {
// return true if the radius given is bigger than the max radius
return (radius > Circle.MAX_RADIUS) ? true : false;
}
Circle.isTooBig(3); // returns true
* Note that JS is loosely typed, which allows for 'duck typing'. If an object has all the methods and properties of class X, then you can treat it as a member of class X, even if it wasn't created with the X() constructor. This isn't always true in other languages.
=== Regular Expressions ===
* Happily, JS supports regular expressions, just like any other decent language. They're done via the RegExp() object, but you don't have to manually create one, as there is a shortcut.
var re1 = RegExp("^foobar$", "i"); // matches the entire string foobar, ignoring case (that's the 'i')
var re2 = /^foobar$/i; // same thing; different way of defining it
* Once you have a RegExp object, you call one of the String class methods to do something with it. The three most useful:
* [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:String:match|match(regexp)]] - match on a string, returning data on the match
* [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:String:search|search(regexp)]] - match on a string, returning the index of the match (or -1)
* [[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:String:replace|replace(regexp, replacementString)]] - replace a string
* [[http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/split|split(regexp)]] - split a string, returning an array of the split strings
* Example:
var re1 = RegExp("^foobar$", "i");
var myString = "FooBar";
var myString2 = "FooBarBaz";
myString.match(re1); // this will match
myString2.match(re1); // this won't (and will return null), since the RegExp specified said we must begin and end with the string 'foobar'
=== Tips and Tricks ===
See the [[Best Practices]] document.