TweetFollow Us on Twitter

Solitaire in JavaScript

Volume Number: 16 (2000)
Issue Number: 6
Column Tag: Web Technologies

Solitaire in JavaScript

by Danny Swarzman

One approach to structuring code with initializers and lambda expressions

Preface

This article introduces JavaScript. I focus on a feature of the language that gets very little mention in books: the ability to use a function definition as an expression. This article provides an example of how such expressions can be used to produce a legible program.

I hope to provide a hint of JavaScript's power to create an interesting user experience under 4.x browsers, by presenting a sample program that creates a Peg Solitaire game in a web page.

Getting started with JavaScript is easy. All you need is a text editor and a browser. But first, let's review some core JavaScript concepts.

JavaScript and HTML

JavaScript interpreters have been written to run in different environments. This article discusses Client-Side JavaScript, which runs in a web browser. The JavaScript code is inside the HTML. It can appear:

  • Between a <SCRIPT> and a </SCRIPT> tag.
  • Inside an HTML tag as the value of an attribute such as onMouseOver, onMouseOut, etc. This code is interpreted when the event occurs.
  • As the value of the HREF attribute in a link or an area tag. In this case, the JavaScript must be prefixed with javascript:. This is interpreted when the user clicks on the link or area.

As the browser interprets the HTML, it creates a hierarchy of objects representing the various parts of the web page. The imbedded JavaScript can access those objects. At the top of the hierarchy is the document, corresponding to the web page.

The JavaScript program can manipulate the contents of the page though these objects. It can change the text that appears in a <TEXTAREA>. It can change the source file for an <IMG> tag. The JavaScript can insert text into the input stream that is currently being interpreted as HTML.

The <SCRIPT> tag

The general form is like this:

<SCRIPT LANGUAGE="JavaScript1.2">
	<!—HIDE
	JavaScript code goes here.
	//NOHIDE—> 
</SCRIPT>

When the browser encounters the <SCRIPT> tag, it starts interpreting the code as JavaScript. The LANGUAGE attribute specifies that JavaScript1.2 or later is required to interpret this script. This will work with most version 4 and later browsers.

If the browser does not interpret at least the specified level of the language, it will try to interpret the text inside the script tags as HTML. To prevent that, the script is enclosed with <!— and —>, marking it as an HTML comment.

When the JavaScript interpreter encounters <!— , it interprets the rest of the line as a comment. The // is another form of rest-of-line JavaScript comment.

Event Handlers

Several tags in HTML have attributes whose value can be text to be interpreted as JavaScript when a particular event occurs. An <A> tag, for example, can have an onMouseOver attribute. Corresponding to the tag is a JavaScript link object. When the browser interprets the tag, the text specified as the onMouseOver attribute becomes the onMouseOver property of the link object. That text is subsequently passed to the JavaScript interpreter when the user moves the mouse over the link.

Order of Interpretation of a Web Page

Every HTML document contains a header and a body. The header is interpreted first. A common practice is to place into the header the JavaScript to generate objects and functions that will be used in the body of the code.

As the browser interprets the body, it creates the enclosure hierarchy of objects corresponding to the various tags. This hierarchy is completely constructed only after the browser has completed interpreting the body.

There is an event generated when the load process is complete. Code that needs to be run only after the enclosure hierarchy has been completely constructed can run in an onLoad event handler.


Figure 1. Peg Solitaire Game

Developing JavaScript

To develop JavaScript to run in a web page, you need a text editor to create an HTML file. The script is embedded in the HTML code. BBEdit is my favorite, but any editor will do.

Test the file by opening it in a browser. I start with Netscape because the error messages are better. When you enter javascript: as the URL in any browser window, Netscape will open a new window in which to display the JavaScript error messages.

In Internet Explorer, you need to set preferences to see error messages. Each error message is displayed as a separate alert. Look at the Web Content subsection of the Web Browser section in the preferences dialog. The relevant choices appear under the heading of Active Content.

As with many web technologies, you may need to make an extra effort to ensure that your code works in all browsers. There are many different strategies for dealing with questions of cross-browser compatibility. That is beyond the scope of this article. The sample code has been tested for recent versions of the two popular browsers running on two popular operating systems.

Another helpful tool is a shell in which you can test fragments of code. An HTML file, enriched with JavaScript, can be used to allow the user to enter text into a text area and invoke the JavaScript interpreter to evaluate it, showing the results in another text area. An example is available on the web. See the references section at the end of this article.

The Evolution of JavaScript

JavaScript is the name of a language promoted by Netscape to complement HTML scripts. This use of JavaScript is called Client-Side JavaScript. Microsoft developed a similar scripting language called JScript. At the time of this writing, there have been five versions of JavaScript, 1.0 through 1.4 and five versions of JScript, 1.0 through 5.0.

In each version, new features have been added and old ones broken. Insuring compatibility with the early versions is a nightmare. Fortunately, around JavaScript 1.2 things began to stabilize.

The European Computer Manufacturers' Association is developing a standard for these languages. Both Netscape and Microsoft are members of the association and both have agreed that their future browsers will conform to the standard. The standard is called ECMAScript. It also is known as E-262 or ECMA262.

The first two editions of the ECMA262 report described a language that was quite limited. The third edition is more comprehensive and corresponds to the implementations in version 5.x of the two popular browsers.

The ECMAScript documents are more difficult reading than the documentation produced by the browser vendors but are more precise. Although they are primarily intended for developers of script interpreters, they are useful reading for anyone who wants a thorough understanding of the language.

There are also interpreters for JavaScript that run outside of the browser environment. These are implementations that run in servers and interpreters imbedded inside other applications.

The example program presented in this article, Peg Solitaire, works with versions of the language starting with JavaScript 1.2. The description of the language is based on the third version of ECMA262.

Some JavaScript Syntax

Variables and Scope

A variable is a container, the atom of the JavaScript cosmos. A container contains a value. A value can be primitive type like number, string, etc. or it can be an object. A variable can contain data of any type.

A variable has a name, its identifier. The identifier is associated with a scope that is either global or local to the function in which the variable is declared. When variables are created with a var keyword inside a function, the identifier is local to the function. Otherwise the variable is global in scope.

For example, the following would create a variable:

var i = 7;

There are actually two actions taken by the interpreter:

  • When the scope is entered, the identifier is associated with a variable, the value of which is undefined.
  • When the statement is interpreted, the value of 7 is assigned to the variable.

A variable may be created by an assignment statement, even if the assignment statement is in the body of a function, without using the keyword var. A variable thus created is global in scope. For example:

i = 7;

creates a global variable and puts 7 into it. The variable will be created when the statement is interpreted, rather than when the scope is entered.

Objects and Initializers

An object is a collection of properties. A property is a container. It has a name and contains a value.

There are several ways to create objects. One way is to use a constructor function. Constructor functions are not used in the sample code, but are described later in this article. Instead, all of our objects will be built with initializers.

An initializer is a list of properties separated by commas. The list is enclosed in curly braces. Consider the statement:

var blob = { color:"red", size:3 };

This creates an object with two properties named color and size. The value contained in the property, color, is the string "red". The left side of the statement, var blob, tells the interpreter to create a variable. The name blob is associated with the newly created variable. If the statement occurs within a function, the scope of the variable is local to the function. If the keyword var is omitted, the scope of the variable will be global.

A script can reference a property directly by name with this syntax:

blob.color

or it can use a string expression to refer to the property:

blob["color"]

Either of these references will return the value red.

The value of a property can be changed by an assignment like:

blob.color = "blue";

or:

blob["color"] = "blue";

New properties can be added to an object:

blob.weight = 3.14;

or:

blob["weight"] = 3.14;

The JavaScript object model is quite different from the object models that appear in C++ and Java. For example, the number and names of properties change dynamically, unlike members and methods. There are many other differences that I do not discuss here.

Arrays Are Objects

In a typical JavaScript object, properties are named with strings. There is a special kind of object in which the properties are named with numbers. These are arrays. Array initializers have square brackets. For example:

var codes = [ "black", "brown", "red", "orange" ];

creates an array object with four numbered properties, starting with 0. The third element in the array, codes[2], contains "red" .

Functions Are Objects

A function is also an object. The initializer for a function object is a function definition. There are two flavors of function definition: function declaration and function expression. They both produce the same kind of object.

A function declaration creates a new object and assigns the object to an identifier. The identifier is local to the scope in which the declaration appears. When a scope is entered, the function declarations are evaluated before any statements in the scope are interpreted. The form of function declaration is:

function Identifier ( FormalParamterListopt ) { 
FunctionBody }

The formal parameter list is a sequence of identifiers separated by commas. The opt indicates that the list may be empty. The function body is a series of statements and function declarations. The parameter list and body are bound to the identifier when the function declaration is interpreted.

An example of a function declaration is:

function a ( x ){return x+1}

The function expression looks much like a function declaration at first glance:

function Identifieropt ( FormalParamterListopt ) { FunctionBody }

The identifier is optional and is ignored if it does appear. This expression yields a value that is a function object. The value is used by the statement in which the expression appears. For example:

var a=function(x){return x+1}

works much like a function declaration except that the function object is created at the time the statement is executed, not when the scope is entered. The object will become the contents of the newly declared variable. The concept of considering a function as a data structure dates back to LISP programming's lambda expressions. These allow for some interesting programming styles.

The syntax of a function call is familiar. The function name is followed by a list of values to be substituted for the formal parameter. For example the expression:

a(4)

will have a value of 5 regardless of the definition, if a is declared with either of the above examples.

A function call is interpreted at runtime. Thus this fragment:

b=a;
b(4)

will also have the value of 5.

An Idiosyncrasy of Syntax (in case you were wondering)

The interpreter considers any statement that begins with the keyword function to be a function declaration. Consider this sequence:

function(x){return x+1}(7)

Although this is not a proper function declaration, the interpreter will accept it and create a function without assigning it to a container. The value of this sequence is the value of the expression statement, 7.

If the sequence starts with any other character, the part beginning with the keyword would be interpreted as a function expression. The following contain function expressions that behave like function calls. The value in each case is 8:

1,function(x){return x+1}(7)
(function(x){return x+1}(7))

Lambda Expressions in Object Initializers

In the sample code, objects are built using object initializers. The initializers for the properties are separated with commas. The function properties are defined with lambda expressions. Consider this example:

var setterGetter =
{
	dataPart:0,
	set: function ( x ) 
	{ 
		this.dataPart = x;
	},
	get: function ()
	{
		return this.dataPart;
	}
}

These functions would be called with statements like:

a=setterGetter.get();
setterGetter.set(7);

The keyword this refers to the current object. Inside this object initializer this.dataPart is synonymous with setterGetter.dataPart.

Note that the fields of an object initializer must be separated with commas. This technique achieves encapsulation of data and scoping. It eliminates some of the clutter involved in using constructor functions when you don't require them.

There is only one copy of setterGetter.dataPart. This is similar to the result of using the keyword static in Java and C++

Constructor Functions

The usual way to do things is to define a function that sets up an object. For example:

function SetterGetter ()
{
	this.dataPart = 0;
	this.set = function ( x ) 
	{ 
		this.dataPart = x;
	};
	this.get = function ()
	{
		return this.dataPart;
	};
}

A call to this function with the new keyword will create an object:

var aSetterGetter = new SetterGetter();

First a new object is created with default properties. Then the constructor is interpreted. This constructor adds properties to the newly created object. The this in the SetterGetter() function refers to the newly created object.

Thus aSetterGetter will acquire properties : aSetterGetter.set(), aSetterGetter.get(), and aSetterGetter.dataPart.

This mechanism allows the creation of something similar to an instance of a class in other languages. There is also a mechanism similar to inheritance. For a thorough discussion about how this works and the contrast with classes in C++ and Java see the Netscape Documents listed in the references section.

The objects in our sample code are each unique. We don't need anything like classes and can get rid of the extra steps required to use constructors.

Peg Solitaire

About the Game

The play area consists of holes containing pegs. They are arranged in a cross consisting of 33 holes. See Figure 1. The game is centuries old and has attracted the attention of many great minds — Gottfried Wilhelm Leibniz, Elwyn Berlekamp, John Conway, Martin Gardner, to name a few.

In the beginning every hole is filled except the one in the center. A move consists of peg jumping over an adjacent peg and landing in an empty hole two spaces away in one of four directions. There are no diagonal jumps. The jumped peg is removed. The object is to remove as many pegs as possible. At the end, one peg remaining constitutes a perfect score.

About the Program

The sample code displays the board in a web page. To view the script, open the web page in your browser and choose the menu command to view the source. The URL is:

http://www.stowlake.com/Solitaire

The program does not play the game. It does enforce the rules and performs housekeeping. Making a play is a two step process:

  • The user clicks on a peg to be moved. A smiling face appears on the peg, indicating that it is selected.
  • The user clicks on the hole where the peg is to go. The peg moves and the jumped peg disappears.

There are rollover effects to indicate legal selections.

The sample is completely contained within one HTML document. There is JavaScript code in both the head and body. The objects that do the work are defined in the head. In the body, JavaScript is used to generate HTML.

Objects Defined in the Head of the HTML Document

There is a set of variables assigned to object initializers in the head of page,

	PegBoard keeps track of which holes contain pegs.
	PegGame makes moves and interprets the rules.
	PegDisplay displays the board on the screen.
	PegControl keeps track of which peg is selected and displays it accordingly.
	PegMouse handles mouse events.
	PegMake generates the HTML for the playing board.

The statements defining these objects appear together, enclosed in HTML script tags specifying JavaScript 1.2.

List of Functions

Some of the functions listed below are described in this article. For the others, see the source code on the web.

	PegBoard.IsEmpty ( where )
	PegBoard.HasPeg ( where )
	PegBoard.RemovePeg ( where )
	PegBoard.PutPeg ( where )
	PegBoard.ClonePosition ()
	PegGame.Jump ( from, delta )
	PegGame.IsLegal ( from, delta )
	PegGame.JumpExistsFrom ( from )
	PegGame.InDeltaSet ( delta )
	PegGame.AreThereAny ()
	PegGame.Refresh ()
	PegDisplay.LoadImages ()
	PegDisplay.ShowImage ( where, what )
	PegDisplay.NormalImage ( where )
	PegDisplay.ShowNormal ( where )
	PegDisplay.ShowOver ( where )
	PegDisplay.ShowGameOver ()
	PegDisplay.ShowSelected ( where )
	PegDisplay.PegNumberToName ( where )
	PegControl.Select ( where )
	PegDisplay.Jump ( where, delta )
	PegDisplay.Redraw ()
	PegDisplay.Reset()
	PegMouse.Over ( where )
	PegDisplay.Out ( where )
	PegDisplay.Click ( where )
	PegMaker.MakePlace ( where )
	PegMaker.MakeRow ( left )
	PegMaker.MakeBoard ()
	PegMaker.MakeBody()
	Resizer.Install ()
	Resizer.Resize () 

where, from, and left are numbers identifying peg positions.

delta is the difference in peg numbers of adjacent peg positions.

what is a string representing the contents of a peg position - emptyHole, hasPeg, selectedPeg, etc.

Generating HTML Code for the Pegs in the Body of the HTML Document

Listing 1: The PegMaker object

PegMaker
PegMaker =
{
	//
	// Generate the strings to make the board in HTML
	//
	// An example, suppose where is 26
	//
	// <A HREF="#" 
	// onMouseOver="self.status=''; return PegMouse.Over(26)
	//	onMouseOut=PegMouse.Out(26) 
	// onMouseDown=self.status=''; return PegMouse.Click(26)>
	//	<IMG SRC="
	// 

	MakePlace: function ( where )
	{
		var result = '<A HREF="#"';
		result+= ' onMouseOver='	
			+ '"self.status=' + "''"+';return PegMouse.
        Over(' + where + ')"';
		result+= ' onMouseOut='
			+ '"PegMouse.Out(' + where + ')"';
		result+= ' onMouseDown='
			+ '"self.status=' + "''"
			+';return PegMouse.Click(' + where + ')">';
		result+= '<IMG src="' + pegdisplay.normalimage(where) + '"';
		result+= 'BORDER="0" HEIGHT="60" WIDTH="60"';
		result+= ' NAME=' 
			+ '"' + PegDisplay.PegNumberToName( where )+ '">';
		result += '</A>';
		return result;
	},
	
	MakeRow: function ( left )
	{
		var result = '<TR>';
		for ( var where=left; where<(left+7); where++ )
			result += '<TD>' + this.MakePlace ( where ) + '</TD>';
		result += '</TR>';
		return result;
	},	
	
	MakeBoard: function ()
	{
		var result = '<TABLE BORDER="0" CELLSPACING="0"'
			+' CELLPADDING="0">';
		for ( var where=24; where<101; where+= 11 )
			result += this.MakeRow ( where );
		result += '</TABLE>';
		return result;
	},
	
	MakeBody: function()
	{
		var boardHTML = this.MakeBoard();
		document.write 
			( '<BODY BGCOLOR="#A7DDDD">' );
		document.write ( '<DIV ALIGN="center">' );
		document.write ( '<P>' );
		document.write ( boardHTML );
		document.write ( '</P>' );
		document.write ( '</DIV>' );
		document.write ( '	</BODY>' );
	}
}

The PegMaker object constructs the body of the web page. MakeBody() is the top level function. It writes a series of strings to the current document. When the call to the document.write() function is executed, the generated HTML is fed to the browser to be interpreted.

MakeBody() wraps the board with tags to display the board centered on the screen and with the appropriate background.

MakeBoard() constructs a string which contains the HTML tags to generate a table.

The table is a square array of cells. We assign numbers to each of the cells:

	   24,25,26,27,28,29,30,
	   35,36,37,38,39,40,41,
	   46,47,48,49,50,51,52,
	   57,58,59,60,61,62,63,
	   68,69,70,71,72,73,74,
	   79,80,81,82,83,84,85,
	   90,91,92,93,94,95,96

creating a 7x7 area inside an 11x11 frame. These elements correspond to the playing area:

	         26,27,28,
	         37,38,39,
	   46,47,48,49,50,51,52,
	   57,58,59,60,61,62,63,
	   68,69,70,71,72,73,74,
	         81,82,83,
	         92,93,94

Position 24 is used to display a message when there are no more legal moves. Position 96 is a reset button. The other elements take no role in the game and display the image noHole. This numbering system simplifies the move calculations done by the PegGame object.

MakePeg() generates a string for each cell. It consists of an <A> tag which contains an <IMG> tag. The <IMG> tag has a NAME attribute formed by the Peg preface followed by the number. For example, NAME="Peg26".

There are attributes, onMouseOver, onMouseDown, and onMouseOut, assigned to each <A> tag . The value of each of these is JavaScript code that calls functions that are defined in the header, PegMouse.Over(), PegMouse.Out(), and PegMouse.Click(). The peg number is passed as an argument to the PegMouse function.

The Main Program

Listing 2: The Main Program

PegDisplay

  <!— The body will be generated by this script. —>
  <SCRIPT LANGUAGE="JavaScript1.2">
  <!—HIDE
    Resizer.Install();				// Set up event handler for resizing
    PegDisplay.LoadImages();		// Preloads images 
    PegMaker.MakeBody();				// Genereate tags-uses preloaded images
    PegControl.Reset();				// Set up the board and show it.
  //NOHIDE—> 
  </SCRIPT>

Instead of having a body in the HTML file, there is a JavaScript that creates the body. This is the top level of the program, playing the role of main(). See Listing 2. This code calls functions defined in the header.

The script initializes an event handler for resize events in Netscape and then loads the images that can appear in the board display. Once these are in place, the HTML that will be the body of the page is generated by the call to PegMaker.MakeBody(). Once the tags are created, the board is set up in the starting position.

Swapping Images

Listing 3: The PegDisplay Object

PegDisplay

PegDisplay = 
{
	// File paths for images that can go on board.
	ImageList :
	{ 
		noHole:"PegSolitGifs/nohole.gif",
		overHole:"PegSolitGifs/overhole.gif",
		emptyHole:"PegSolitGifs/emptyhole.gif",
		hasPeg:"PegSolitGifs/haspeg.gif",
		overPeg:"PegSolitGifs/overpeg.gif",
		selectedPeg:"PegSolitGifs/selectpeg.gif",
		gameOver:"PegSolitGifs/gameover.gif",
		resetButton:"PegSolitGifs/reset.gif"
	},

	StoredImages : new Array(),
	
	// Make sure all the images are in memory. Doing this makes
	// the display of these images smooth.
	LoadImages : function ()
	{
		for ( imagePath in PegDisplay.ImageList )
		{
			PegDisplay.StoredImages[imagePath] = new Image();
			PegDisplay.StoredImages[imagePath].src = PegDisplay.ImageList[imagePath];
		}
	},
	
	// Show specified image and place
	ShowImage: function ( where, what )
	{
		var name = this.PegNumberToName(where);
		document[name].src=
			this.ImageList[what];
	},
	// Show the no rollover, not selected image for where.
	NormalImage: function ( where )
	{
		var what = 
			PegBoard.IsEmpty ( where )
				? "emptyHole"
				: PegBoard.HasPeg ( where )
					? "hasPeg"
					: where == PegBoard.resetPosition
						? "resetButton"
						: "noHole";
		return what;
	},
	// 
	// All these Show... functions assign
	// a file path to the source for the 
	// image.
	//	
	ShowNormal: function ( where )
	{
		PegDisplay.ShowImage ( where,
			PegDisplay.NormalImage(where) );
	},	
	// Hilite hole that can be destination of current selection or
	// peg that can make a legal move.
	ShowOver: function ( where )
	{
		if ( PegGame.IsLegal ( PegControl.selection, 
			(where-PegControl.selection)/2 ) )
				this.ShowImage ( where, "overHole" );
		else if ( where!=PegControl.selection 
			&& PegGame.JumpExistsFrom ( where ) )
				this.ShowImage ( where, "overPeg" );
	},
	
	ShowGameOver: function ()
	{
		this.ShowImage ( PegBoard.gameOverPosition, "gameOver" );
	},
	
	ShowSelected: function ( where )
	{
		if ( where )
			this.ShowImage ( where, "selectedPeg" );
	},
	
	// Form the name to refer to the peg.
	PegNumberToName : function ( where )
	{
		return "Peg" + where;
	}

}

The program reacts to mouse events by changing the .gif that is assigned to one or more peg positions. The .gif files are referred to by these names:

  • noHole is the image displayed outside the playing area.
  • emptyHole is the normal appearance of an empty hole.
  • overHole appears when the mouse is over a hole to which the currently selected peg can jump.
  • hasPeg is the normal appearance of a peg.
  • selectedPeg shows a peg ready to move.
  • overPeg is displayed when the mouse is over a peg for which a legal move exists-that is, a peg that can become selected.
  • gameOver is displayed in position 24 when there are no legal moves on the board.
  • resetButton is always displayed in position 96.

These are shown in Figure 2.

The function PegDisplay.LoadImages() sends requests to load the .gif files. It is called before they are actually needed to display. This prevents an annoying delay the first time the user moves the mouse over a selectable peg. For each .gif that it is loaded, a new Image object is created and assigned to an element of the array PegDisplay.ImageList. This is the same type of object that the browser creates for an <IMG>.

The actual request to get the file comes when this statement is executed:

PegDisplay.StoredImages[imagePath].src = 	PegDisplay.ImageList[imagePath];

This assigns a URL from the PegDisplay.ImageList to the src property of the newly created Image object. Image objects watch for a change in the src property. When it changes, a handler in the Image object tries to get the image data. If the image hasn't already been loaded, it sends a request to the server to get the specified image file. If the Image object was created by an <IMG> tag, the display on the screen will also change.

The Image objects created by tags in the peg board each have a NAME attribute based on the position number. The value of that attribute is used as the name of a property in the document object. For example, document["Peg26"] refers to Image object created by the browser when it interpreted the <IMG> tag that specified the attribute NAME="Peg26". When the name of a .gif file is placed in the src property of that object, the image displayed in position 26 will change accordingly.


Figure 2. Images that are swapped in the board display.

Conclusions

JavaScript has some powerful features that make it an interesting programming language, and it offers many choices for programming style. Even if you've developed a good understanding of how to create a lucid program in C++ or Java, you'll find that JavaScript presents its own set of challenges.

This article showed that a practical program can be created using lambda expressions. They offer a means to create clean code. There are other uses for lambda expressions. This article showed only one application.

Some of the mechanics of interaction with the browser were also demonstrated. As the standard for web pages evolves, the role of JavaScript will grow. We can only hope that the cross-browser compatibility problems will abate.

References

The code described in this article is available at these locations:

Choose the menu command from your browser to view the source.

If you work with JavaScript, you will need to download the documentation on the net. There are several books, though the language is a little too new and still changing too fast for books to keep up. My favorite is JavaScript, The Definitive Guide by David Flanagan, published by O'Reilly, although it is not definitive.

Netscape publishes a variety of documents on JavaScript. A good starting point would be the Client-Side JavaScript Guide:

http://developer.netscape.com/docs/manuals/js/client/jsguide/contents.htm

Microsoft calls its version of JavaScript JScript. Documentation is at:

http://msdn.microsoft.com/scripting/default.htm?/scripting/JScript/doc/Jstoc.htm

The official standard is ECMAScript. The publication of the standard lags behind the implementation in browsers. The features illustrated here will be described in the third edition of the ECMA standard. See:

http://ecma.ch/stand/ECMA-262.htm

A shell to test code fragments in JavaScript is available at:

http://www.stowlake.com/JavaScriptShell/

Credits

Thanks to Victoria Leonard for producing the artwork. Thanks to Bob Ackerman, Mark Terry and Victoria Leonard for proofreading.

Thanks to Jan van den Beld, ECMA Secretary General, for explaining some fine points of the ECMA- 262 standard.


Danny Swarzman writes programs in JavaScript, Java, C++ and other languages. He also plays Go and grows potatoes. You can contact him with comments and job offers. mailto:dannys@stowlake.com, http://www.stowlake.com

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

MacFamilyTree 8.2.5 - Create and explore...
MacFamilyTree gives genealogy a facelift: modern, interactive, convenient and fast. Explore your family tree and your family history in a way generations of chroniclers before you would have loved.... Read more
Hopper Disassembler 4.3.2- - Binary disa...
Hopper Disassembler is a binary disassembler, decompiler, and debugger for 32- and 64-bit executables. It will let you disassemble any binary you want, and provide you all the information about its... Read more
GraphicConverter 10.5.1 - $39.95
GraphicConverter is an all-purpose image-editing program that can import 200 different graphic-based formats, edit the image, and export it to any of 80 available file formats. The high-end editing... Read more
Delicious Library 3.7 - Import, browse a...
Delicious Library allows you to import, browse, and share all your books, movies, music, and video games with Delicious Library. Run your very own library from your home or office using our... Read more
Adobe Animate CC 2017 18.0.0.107 - Anima...
Animate CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Flash Professional customer). Animate CC 2018 (was Flash CC) lets you... Read more
Adobe After Effects CC 2018 15.0 - Creat...
After Effects CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous After Effects customer). The new, more connected After Effects CC... Read more
Adobe Premiere Pro CC 2018 12.0.0 - Digi...
Premiere Pro CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Premiere Pro customer). Adobe Premiere Pro CC 2018 lets you edit... Read more
Alarm Clock Pro 10.3 - $19.95
Alarm Clock Pro isn't just an ordinary alarm clock. Use it to wake you up in the morning, send and compose e-mails, remind you of appointments, randomize the iTunes selection, control an internet... Read more
Adobe Lightroom 20170919-1412-ccb76bd] -...
Adobe Lightroom is available as part of Adobe Creative Cloud for as little as $9.99/month bundled with Photoshop CC as part of the photography package. Lightroom 6 is also available for purchase as a... Read more
Adobe Illustrator CC 2018 22.0.0 - Profe...
Illustrator CC 2018 is available as part of Adobe Creative Cloud for as little as $19.99/month (or $9.99/month if you're a previous Illustrator customer). Adobe Illustrator CC 2018 is the industry... Read more

ICEY (Games)
ICEY 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: ICEY is a 2D side-scrolling action game. As you follow the narrator's omnipresent voice, you will see through ICEY's eyes and learn the... | Read more »
The best new games we played this week -...
We've made it, folks. Another weekend is upon us. It's time to sit back and relax with the best new releases of the week. Puzzles, strategy RPGs, and arcade games abound this week. There's a lot of quality stuff to unpack this week, so let's hop... | Read more »
Wheels of Aurelia (Games)
Wheels of Aurelia 1.0.1 Device: iOS Universal Category: Games Price: $3.99, Version: 1.0.1 (iTunes) Description: | Read more »
Halcyon 6: Starbase Commander guide - ti...
Halcyon 6 is a well-loved indie RPG with stellar tactical combat and some pretty good writing, too. It's now landed on the App Store, so mobile fans, if you're itching for a good intergalactic adventure, here's your game. Being a strategy RPG, the... | Read more »
Game of Thrones: Conquest guide - how to...
Fans of base building games might be excited to know that yet another entry in the genre has materialized - Game of Thrones: Conquest. Yes, you can now join the many kingdoms of the famed book series, or create your own, as you try to conquer... | Read more »
Halcyon 6: Starbase Commander (Games)
Halcyon 6: Starbase Commander 1.4.2.0 Device: iOS Universal Category: Games Price: $6.99, Version: 1.4.2.0 (iTunes) Description: An epic space strategy RPG with base building, deep tactical combat, crew management, alien diplomacy,... | Read more »
Legacy of Discord celebrates its 1 year...
It’s been a thrilling first year for fans of Legacy of Discord, the stunning PvP dungeon-crawling ARPG from YOOZOO Games, and now it’s time to celebrate the game’s first anniversary. The developers are amping up the festivities with some exciting... | Read more »
3 reasons to play Thunder Armada - the n...
The bygone days of the Battleship board game might have past, but naval combat simulators still find an audience on mobile. Thunder Armada is Chinese developer Chyogames latest entry into the genre, drawing inspiration from the explosive exchanges... | Read more »
Experience a full 3D fantasy MMORPG, as...
Those hoping to sink their teeth into a meaty hack and slash RPG that encourages you to fight with others might want to check out EZFun’s new Eternity Guardians. Available to download for iOS and Android, Eternity Guardians is an MMORPG that lets... | Read more »
Warhammer Quest 2 (Games)
Warhammer Quest 2 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: Dungeon adventures in the Warhammer World are back! | Read more »

Price Scanner via MacPrices.net

Save $100 on 13″ MacBook Airs, prices start a...
Adorama has 2017 13″ MacBook Airs on sale today for $100 off MSRP including free shipping. Adorama charges NY & NJ sales tax only: – 13″ 1.8GHz/128GB MacBook Air (MQD32LL/A): $899, $100 off MSRP... Read more
1.4GHz Mac mini available for $399, $100 off...
TigerDirect has the 1.4GHz Mac mini on sale today for $399 including free shipping. Their price is $100 off MSRP, and it’s the lowest price available for this model. Although currently out of stock,... Read more
21″ 2.3GHz iMac on sale for $999, save $100
MacMall has the 21″ 2.3GHz iMac (MMQA2LL/A) on sale today for $999 including free shipping. Their price is $100 off MSRP, and it’s the lowest price available for this model. Read more
12″ iPad Pros on sale for $50 off MSRP, no ta...
Adorama has 12″ iPad Pros on sale today for $50 off MSRP. Shipping is free, and Adorama charges sales tax in NY & NJ only: – 12″ 64GB iPad Pro: $749, save $50 – 12″ 256GB iPad Pro: $899, save $50... Read more
9″ iPads on sale for $30 off, starting at $29...
MacMall has 9″ iPads on sale for $30 off including free shipping: – 9″ 32GB iPad: $299 – 9″ 128GB iPad: $399 Read more
Apple restocks full line of refurbished 13″ M...
Apple has restocked a full line of Apple Certified Refurbished 2017 13″ MacBook Pros for $200-$300 off MSRP. A standard Apple one-year warranty is included with each MacBook, and shipping is free.... Read more
13″ 3.1GHz/256GB MacBook Pro on sale for $167...
Amazon has the 2017 13″ 3.1GHz/256GB Space Gray MacBook Pro on sale today for $121 off MSRP including free shipping: – 13″ 3.1GHz/256GB Space Gray MacBook Pro (MPXV2LL/A): $1678 $121 off MSRP Keep an... Read more
13″ MacBook Pros on sale for up to $120 off M...
B&H Photo has 2017 13″ MacBook Pros in stock today and on sale for up to $120 off MSRP, each including free shipping plus NY & NJ sales tax only: – 13-inch 2.3GHz/128GB Space Gray MacBook... Read more
15″ MacBook Pros on sale for up to $200 off M...
B&H Photo has 15″ MacBook Pros on sale for up to $200 off MSRP. Shipping is free, and B&H charges sales tax in NY & NJ only: – 15″ 2.8GHz MacBook Pro Space Gray (MPTR2LL/A): $2249, $150... Read more
Roundup of Apple Certified Refurbished iMacs,...
Apple has a full line of Certified Refurbished 2017 21″ and 27″ iMacs available starting at $1019 and ranging up to $350 off original MSRP. Apple’s one-year warranty is standard, and shipping is free... Read more

Jobs Board

Project Engineer, *Apple* Education Profess...
Project Engineer, Apple Education Professional Services Job Number: 113143353New York City, New York, United StatesPosted: Oct. 17, 2017Weekly Hours: 40.00 Job Read more
Commerce Software Engineer, *Apple* Media P...
Commerce Software Engineer, Apple Media Products Job Number: 113092072New York City, New York, United StatesPosted: Oct. 19, 2017Weekly Hours: 40.00 Job Summary With Read more
Engineering Manager, *Apple* Retail Enginee...
# Engineering Manager, Apple Retail Engineering Job Number: 58139948 Santa Clara Valley, California, United States Posted: 20-Oct-2017 Weekly Hours: 40.00 **Job Read more
*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Commerce Engineer, *Apple* Media Products -...
Commerce Engineer, Apple Media Products (New York City) Job Number: 113028813New York City, New York, United StatesPosted: Sep. 20, 2017Weekly Hours: 40.00 Job Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.