JavaScript, the language, is
Some links:
Here's your first Javascript program (a one-liner, of course):
alert("Hello, world.");
This program (a.k.a. script) consists of
one statement which is a call to
the function that is the value of
the property named alert of
the global object.
There are at least four ways to run JavaScript code:
<html>
<head>
<title>A Greeting</title>
</head>
<body>
<p>My first JavaScript program:</p>
<script>
alert("Hello, World.");
</script>
</body>
</html>
JavaScript programs can run not only in web browsers, but also virtual worlds, Adobe Photoshop, and other environments. When running inside a web browser, your scripts have access to windows, menus, pop-ups, dialog boxes, textareas, anchors, frames, histories, cookies and other objects.
Here's more complicated program. Try it in the runner, the shell, or inside an XHTML document.
// A script with two functions and code to exercise them
var today = function () {
return new Date();
};
var cubed = function (x) {
return x * x * x;
};
var n = 10;
document.write("<b>Some cubes for " + today() + "</b>");
for (var i = 0; i < n; i += 1) {
document.write("<br />" + cubed(i));
}
The language architecture is rather simple:
That's it. Things that seem like basic concepts, like functions, arrays, and regular expressions are just kinds of objects, though syntactically sugared.
The ECMAScript language standard defines a core set of types, values, objects, properties and functions. A conforming implementation may add extra types, values, objects, properties and functions. JavaScript 1.5 conforms to ECMA-262, edition 3.
If you come from the C, C++, Java, Ada world where compilers seem to check everything, remember Javascript is a dynamic language like Perl, Python, PHP, PostScript, Smalltalk, Self, etc:
There are 6 types
| Type | Values of the Type |
|---|---|
| Undefined | Only one value: undefined. |
| null | Only one value: null. |
| Boolean | Only two values: true and false. |
| Number | The IEEE 754 floating point values, expressible in decimal
or hex. (JavaScript also supports octal literals but ECMA-262
ed. 3 does not.) Examples:
|
| String | Quote-delimited strings of zero or more UTF-16 code units. Examples:
|
| Object | Everything that isn't one of the above five types. |
The first five above are called primitive types, and their values can be stored directly. Object values are always accessed through references.
JavaScript is pretty loose with types, when expressions don't have the expected type JavaScript will often compute a derived expression that does.
Complete details are in Section 9 of the ECMAScript Standard.
A program is a sequence of statements and function declarations. The kinds of statements are:
Objects have properties. Access the properties with either dot or square bracket notation. Note: You don't make a class and declare the properties; you just start using them. You can even delete properties.
var x = {};
x.age = 17;
x.height = 65.3;
var score = x.age * x["height"];
var z = {age: 30, color: "red", total: 3};
z.last = true;
var rat = {triple: {a:4, b:undefined, c:{4:null}}, 7: "stuff"};
delete z.age;

An array is a kind of object with "numeric properties." Fortunately JavaScript provides a convenient syntax for them, too:
var a = [];
var b = [1, 5, 25];
var c = new Array(); // Lame way to say []
var d = new Array{4, 5, 6); // Lame way to say [4, 5, 6]
var e = new Array(10); // 10 cells, all undefined.
var f = a.length;
var g = [1, true, [1,2], {x:5, y:6}, "Hi"];
var h = {triple: {a:4, b:"dog", c:[1,null]}, 7: "stuff"};
var i = [h.triple.a, h[7]];
alert(g[1]); // Alerts true.
alert(g[2][0]); // Alerts 1.
alert(g.length); // Alerts 5.
g[10] = 100; // Makes g[5] through g[9] undefined.
alert(g.length); // Alerts 11.
g.length = 2; // Now g is just [1, true].
var a = new Array(3); a[0] = 1; a[1] = "hello"; a[2] = a;
You can define a function three ways
function successor (x) {
return x + 1;
}
var sum = function (x,y) {return x + y;}
var predecessor = new Function("x", "return x - 1;");
The latter two make it clear that a function is just an object. The third one, though interesting, is very slow (why?) and considered evil.
Because a function is an object,
Examples:
function plusSix (x) {return x + 6;}
function squared (x) {return x * x;}
function twice (f, x) {return f(f(x));}
document.write(twice(plusSix, 5) + " ");
document.write(twice(squared, 4) + " ");
function compose (f, g) {return function(x) {return g(f(x));}}
var squareThenPlusSix = compose(squared, plusSix);
document.write(squareThenPlusSix(10) + " ");
document.write(compose(plusSix, squared)(5) + " ");
document.write("twice expects " + twice.length + " arguments");
If you call a function that is a property of an object, within that function the expression this refers to the containing object.
var x = {a:1, b:function(x) {return x + this.a;}};
document.write(x.b(2));
will write 3.
The expression this is evaluated dynamically, not statically:
function f(x) {return x + this.a;}
var x = {a:10, b:f};
document.write(x.b(2));
will write 12. This is starting to look useful...
var p = {
x: 0,
y: 0,
move: function(dx, dy) {this.x += dx; this.y += dy;},
reflect: function() {this.x = -this.x; this.y = -this.y;}
};
p.move(5, 4);
p.reflect();
document.write(p.x + " " + p.y);
This made something that looks like a point object. What if we want a whole bunch of points?
Check this out:
function Point() {
this.x = 0;
this.y = 0;
this.move = function(dx, dy) {this.x += dx; this.y += dy;}
this.reflect = function() {this.x = -this.x; this.y = -this.y;}
return this;
};
var p = new Point(); // The 'new' is crucial!
p.move(52, 40);
p.reflect();
document.write(p.x + " " + p.y);
When you call the function with new, the function you call behaves as a constructor which means:
That constructor we just wrote isn't very good because
One way (but perhaps not the best way) to fix this is to add global functions (ugh) and assign these to the method properties:
function point_move(dx, dy) {this.x += dx; this.y += dy;}
function point_reflect() {this.x = -this.x; this.y = -this.y;}
function point_to_string() {return "(" + this.x + "," + this.y + ")";}
function Point(x, y) {
this.x = x || 0;
this.y = y || 0;
this.move = point_move;
this.reflect = point_reflect;
this.toString = point_to_string;
};
var p = new Point();
var q = new Point(3, 7);
p.move(52, 40);
p.reflect();
q.move(1, 1)
document.write(p + " " + q);
Now suppose you wanted to add a "move_to_origin" method. You could add it to just one object:
p.moveToOrigin = function() {this.x = 0; this.y = 0;}
p.moveToOrigin();
q.moveToOrigin(); // ERROR: q has no moveToOrigin property
document.write(p + " " + q);
But to add it to every point object, even those not yet created, you can rewrite the constructor, or add the method to the prototype of any existing point object.
Point.prototype.moveToOrigin = function() {this.x = 0; this.y = 0;}
p.moveToOrigin();
q.moveToOrigin();
document.write(p + " " + q);
Hey! This looks like a better way to do methods. We don't have to pollute the global namespace:
function Point(x, y) {
this.x = x || 0;
this.y = y || 0;
};
Point.prototype.move = function(dx, dy) {this.x += dx; this.y += dy;}
Point.prototype.reflect = function() {this.x = -this.x; this.y = -this.y;}
Point.prototype.toString = function() {return "(" + this.x + "," + this.y + ")";}
var q = new Point(3, 7);
This works because If you try to access (read the value of or call), say, x.p and x doesn't have property p, JavaScript will (recursively) look for p in x.__proto__. (And remember the value of x.__proto__ is set to the value of y.prototype where y is the constructor that constructed x.)
Any object can have a prototype, but prototypes are most useful on constructor functions.
You can make deep "class hierarchies" once you are comfortable with prototype chains, but if you find yourself doing this frequently, or making particularly deep hierarchies, ask yourself why you are using JavaScript.
One way to wing this, using a classic (pun intended) example:
function Person(name, birthday) {
this.name = name || "Unknown"
this.birthday = birthday;
}
Person.prototype.age = function() {
return new Date().getTime() - this.birthday.getTime();
}
function Employee(name, birthday, id) {
Person.apply(this, [name, birthday]);
this.id = id;
}
Employee.prototype = new Person();
function Student(name, birthday, gpa) {
Person.apply(this, [name, birthday]);
this.gpa = gpa;
}
Student.prototype = new Person();
function Administrator(name, birthday, id) {
Employee.apply(this, [name, birthday, id]);
}
Administrator.prototype = new Employee();
function Instructor(name, birthday, id, department) {
Employee.apply(this, [name, birthday, id]);
this.department = department;
}
Instructor.prototype = new Employee();
One problem with this approach is the prototypes lose their constructor property, which hurts you if you are trying to do something like Java's getClass() with it. You have to fall back to using instanceof; Object.prototype.toString.call() won't work for things you define. Or go ahead and hack the constructor property back in!! Why are we doing this again???
If you still want to do this kind of stuff, Douglas Crockford has a page showing several different ways to do it. He concludes that "Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies. Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive." Good advice. Use JavaScript's dynamic features; don't let your thinking get mired in the rigidity of static classes.
JavaScript
break else instanceof true
case false new try
catch finally null typeof
continue for return var
default function switch void
delete if this while
do in throw with
abstract enum int short
boolean export interface static
byte extends long super
char final native synchronized
class float package throws
const goto private transient
debugger implements protected volatile
double import public
Syntax of identifiers
| Escape Sequence | Code Point (in Hex) | Character Name |
|---|---|---|
| \b | 8 | Backspace |
| \t | 9 | Horizontal Tab |
| \n | A | Line Feed |
| \v | B | Vertical Tab |
| \f | C | Form Feed |
| \r | D | Carraige Return |
| \" | 22 | Double Quote |
| \' | 27 | Single Quote |
| \\ | 5C | Backslash |
| \xh1h2 (two hex digits) |
10 * h1 + h2 | - |
| \uh1h2h3h4 (four hex digits) |
1000 * h1 + 100 * h2 + 10 * h3 + h4 | - |
From highest to lowest precedence
| Operators | Associativity | Description |
|---|---|---|
| . [] |
L | member (rhs cannot start with a digit) member |
| () new |
N/A | call create instance |
| ++ -- |
N/A | postfix increment postfix decrement |
| ! ~ - + ++ -- typeof void delete |
R | logical not bitwise not unary negation unary plus prefix increment prefix decrement type name eval and return undefined delete |
| * / % |
L | multiply divide modulo |
| + - |
L | add subtract |
| << >> >>> |
L | left shift arithmetic right shift (sign fill) logical right shift (zero fill) |
| < <= > >= in instanceof |
L | less than less than or equal greater than greater than or equal has property has type |
| == != === !== |
L | equals not == equals and same type not === |
| & | L | bitwise-and |
| ^ | L | bitwise xor |
| | | L | bitwise or |
| && | L | short-circuit logical and |
| || | L | short-circuit logical or |
| ?: | R | conditional |
| = += -= *= /= %= <<= >>= >>>= &= ^= |= |
R | assignment |
| , | L | comma |
Good to know:
Entities in bold are specific to JavaScript 1.5 and not ECMA-262.
| Name | Properties | __proto__ | Notes |
|---|---|---|---|
| Global | NaN Infinity undefined Math eval() parseInt() parseFloat() isNaN() isFinite() decodeURI() decodeURIComponent() encodeURI() encodeURIComponent() Object() Function() Array() String() Boolean() Number() Date() RegExp() Error() EvalError() RangeError() ReferenceError() SyntaxError() TypeError() URIError() | [implementation dependent] | Not directly accessible |
| Object | length prototype | Function.prototype | |
| Object.prototype | constructor toString() toLocaleString() valueOf() hasOwnProperty() isPrototypeOf() propertyIsEnumerable() toSource() watch() unwatch() | null | |
| Function | length prototype | Function.prototype | instance properties: length prototype |
| Function.prototype | constructor |
Object.prototype | |
| Array | length prototype | Function.prototype | instance properties: length |
| Array.prototype | constructor index input concat() join() pop() push() reverse() shift() slice() splice() sort() unshift() every() some() filter() forEach() map() indexOf() lastIndexOf() | Object.prototype | |
| String | length prototype fromCharCode() | Function.prototype | instance properties: length |
| String.prototype | constructor toString() valueOf() charAt() charCodeAt() indexOf() lastIndexOf() localeCompare() match() concat() split() splice() slice() substring() replace() search() toLowerCase() toLocaleLowerCase() toUpperCase() toLocaleUpperCase() (plush a bunch of crap methods that write out crappy HTML — don't use that crap) | Object.prototype | |
| Boolean | length prototype | Function.prototype | |
| Boolean.prototype | constructor toString() valueOf() | Object.prototype | |
| Number | length prototype MAX_VALUE MIN_VALUE NaN NEGATIVE_INFINITY POSITIVE_INFINITY | Function.prototype | |
| Number.prototype | constructor toString() toLocaleString() valueOf() toFixed() toPrecision() toExponential() | Object.prototype | |
| Math | E PI SQRT_2 SQRT1_2 LN2 LN10 LOG2E LOG10E abs() sin() cos() tan() acos() asin() atan() atan2() exp() log() ceil() floor() min() max() pow() random() round() sqrt() | Object.prototype | |
| Date | length prototype parse() UTC() | Function.prototype | |
| Date.prototoype | constructor toString() toDateString() toTimeString()
toLocaleString() toLocaleDateString() toLocaleTimeString()
valueOf() getTime() getFullYear() getUTCFullYear() getMonth()
getUTCMonth() getDate() getUTCDate() getDay() getUTCDay()
getHours() getUTCHours() getMinutes() getUTCMinutes()
getSeconds() getUTCSeconds() getMilliseconds() getUTCMilliseconds()
getTimezoneOffset() setTime() setMilliseconds()
setUTCMilliseconds() setSeconds() setUTCSeconds()
setMinutes() setUTCMinutes() setHours() setUTCHours()
setDate() setUTCDate() setMonth() setUTCMonth()
setFullYear() setUTCFullYear() toUTCString()
|
Object.prototype | |
| RegExp | length prototype | Function.prototype | instance properties: source global ignoreCase multiline lastIndex |
| RegExp.prototype | constructor exec() test() toString() | Object.prototype | |
| Error | length prototype | Function.prototype | |
| Error.prototype | constructor name message toString() | Object.prototype | |
| EvalError | length prototype | Function.prototype | |
| EvalError.prototype | constructor name message() | Error.prototype | |
| RangeError | length prototype | Function.prototype | |
| RangeError.prototype | constructor name message() | Error.prototype | |
| ReferenceError | length prototype | Function.prototype | |
| ReferenceError.prototype | constructor name message() | Error.prototype | |
| SyntaxError | length prototype | Function.prototype | |
| SyntaxError.prototype | constructor name message() | Error.prototype | |
| TypeError | length prototype | Function.prototype | |
| TypeError.prototype | constructor name message() | Error.prototype | |
| URIError | length prototype | Function.prototype | |
| URIError.prototype | constructor name message() | Error.prototype |
Host environments provide lots of their own objects. You're likely to see these in most web environments:
Anchor Applet Area Arguments Button Checkbox Crypto Document Event FileUpload Form Frame Hidden History HTMLElement Image Input Layer Link Location MimeType Navigator Option Password Plugin Radio Reset Screen Select Style Submit Text TextArea Window
JavaScript has special syntactic sugar for regular expressions, for example
/dog/
/JavaScript/i
/moe|larry|curly/i
/colo(u)?r/
/<([^>]*)>[^<]*<\/\1>/
/\d{5}(-\d{4})?/
JavaScript's regular expression language is pretty "standard":
Important:
Each property has between zero and four attributes:
| Attribute | Description |
|---|---|
| ReadOnly | writes to the property will be ignored |
| DontEnum | property will be skipped in a for-in enumeration |
| DontDelete | deletion attempts will be ignored |
| Internal | not accessible in normal code |
A couple aspects of JavaScript aren't so easy to explain just by using the notion of objects with properties. Examples:
These things, and others like them, are described in terms of execution contexts in Section 10 of the ECMAScript standard.