JavaScript Stuff I Always Forget

7/18/2011

 

Sources

·         http://www.w3schools.com/js

·         http://www.readwriteweb.com/hack/2010/12/6-free-javascript-e-books.php

·         [Using XML with Javascript] http://www.w3schools.com/dom/default.asp

Stuff I always forget

·         Missing trailing parameters on a functional call come through as undefined. Extra trailing parameters are simply ignored.

·         It’s button.disabled = true, not button.enabled = false;

·         On IE8- its .attachEvent, on everything else its addEventListener

·         Events are all lower case, properties and methods are camel-case, class names are Pascal case (Math.abs(myVar)). ??Not a hard & fast rule??

·         document.getElementBy[Id|Name]. All are case sensitive.

·         Inline elements (such as span) cannot have a width set when running in standards mode (use quirks or set display:inline-block)

·         var outside a fn is global

·         Supports *=, +=, ++n, &&, || etc. ??No XOR op though??

·         Supports ternary operator (boolCondition?result1:result2);

·         Supports for (x in y), but note x is the name of every property on y (not the object itself). For an array the name is the index, so it works as expected.

·         Supports try {…} catch(err) {…} finally {…}
where err is the type thrown ([string|integer|bool|object) by an error or by a throw statement (throw "Oh no!";). Language

·         Setting document.location.href to change the URL / reload the page

·         \ inside a string is an escape character. If nothing follows, it becomes a string continuation character and the string’s content continues unescaped on the following line. E.g.
“hello \
world”

·         Odd types: null, false, undefined, NaN, Number.[MAX|MIN]_VALUE, Number.[NEGATIVE|POSITIVE]_INFINITY

·         Math functions and constants are buried away on the Math class.

o   min, max, PI, random() [0 to 1), round (nearest integer only), cos et al.

·         Number

o   Constructor can be used like a  cast (var x = Number(“123”))

o   .ToExponential(x), toFixed(x), toPrecision(x), toString

·         var p = new RegExp(pattern [, modifiers]) is same as var p =/pattern[/modifiers]

·         navigator object describes the browser (e.g. navigator.cookieEnabled, .userAgent, etc)

·         escape(string) / unescape(string)
HTML escape /unescape

·         encodeURIComponent(string) / decodeURIComponent(string)
URL escape / unescape

·         cookie format: ‘x=y[;x2=y2…’
Accessed via document.cookie. ??Cookie values should be escaped? ??
Magic cookie keys:

o   expires
When the cookie expires. If absent, cooke is a session cookie.

o   domain, path
Only if the domain/path matches is the cookie valid. Domain cannot be set for session cookies.

o   secure
Send over HTTPs

o   httponly
Cookie is round tripped, but not visible to the browser through code

·         Timers

o   var t =setTimeout(‘javascript’, delayInMs)

o   t.clearTimeout()

·         Switch syntax is: swith(n) { case o:…;break; default:}. Code is allowed to drop through on absence of break.
?? Can I switch on non-numeric types? ??

·         Properties can be accessed as x.property or x["property"].

·         There is no control over by-reference parameter passing in Javascript. Value types are by value, objects are by reference, but strings are a special case. In Javascript (non-literal) strings are objects, but they are still passed by value only.

·         HTML class attribute, multi-parameter CCS, etc: ARE SPACE DELIMITED NOT COMMA DELIMITED. Grrr.

Alerts

·         confirm(text) = alert() with OK [true]/Cancel[false] buttons

·         prompt(text, defaultInputText) = ask user for a value

Loops

·         for, while, do {} while

·         break is supported

·         continue is supported

·         for (x in y) is supported

Objects

·         Look like property bags / JSON. Structure declared on the fly:
 var me={firstName:"Dave", hair:"Groovey"};
and can be added on the fly: me.someNewProperty = 3;

·         Methods can be added the same way: me.someNewMethod = function(…). Body of methods can use the ‘this.’ Pointer.

·         Properties and methods can be removed through the delete command: delete me.someNewProperty

·         Properties can be tested for using the ‘in’ operator (if (someNewProperty in me))

·         document.write(someObj) dumps all the values in the bag, but not the keys

·         JSON.stringify / JSON.parse

·         Undefined (e.g. x.IJustMadeThisPropertyUp) properties return undefined.

·         ‘{}’ is syntactically equivalent to ‘new Object();’

Prototypes and Class-like functionality

Javascript has prototypes instead of classes. There is a typeof command, but it only works with primitive types (returning ‘object’ for all objects).

, but…

·         By convention (only), object constructors are pascal cased (e.g.
function Book(title, author) {

    this.Title = title;

    this.Author = author;

    this.getDisplayString = function () { return this.Author + ", " + this.Title; }

}

var b = new Book("My Rise To Fame""Dave B");

alert(b.getDisplayString());

·         The code above would work as is without the new operator, but then the ‘constructor’ property would be set to Object rather than the method we stuck ‘new’ in front of.

·         The prototype for an object x is available through its constructor (e.g. Book.prototype, myBook.constructor.prototype)

·         All objects support toString() as toString() is implemented on Object

·         Reading x.y will fall back to reading x.constructor.prototype.y if x doesn’t implement y itself. Writing x.y never falls back to the prototype. Writing x.constructor.prototype.y sets the values for all object using that prototype (that haven’t set x.y)

·         Methods like .hasOwnProperty and .propertyIsEnumerable are available to eliminate ‘junk infrastructure’ references.

·         Core objects are not protected (you can add stuff to core prototypes such as Object and Array), but doing so has global impact.

Arrays

?? Are arrays implemented as objects with numeric property names and a length? ??

·         Declaration

o   var x = new Array([int optional size])

o   var x = ["Hello", "world"];

·         Arrays support

o   .length

o   .concat(array2 [,arrayN])

o   .join / .slice (convert to string from string)
.toString() === .join(",");

o   .push / .pop
Use ‘[]’ on its own to create an empty array (e.g. var myStack = [];

o   .unshift(e1 [, eX]) – insert elements at start of array and returns new length

o   .splice(start, removeCount [, e1 [,eN]])
removes removeCount elements at position start and inserts N elements at the removal position. removeCount and N do not need to have the same value. N can be 0.

o   .reverse
In place sort.

o   .sort([function(a,b)])
In place sort. Function(a,b) need to return -1, 0, or 1 (for a<b, a=b, a>b)

Strings

·         toUpperCase(…), indexOf(…), replace(…), charAt(…), length

·         txt.link(url) wraps txt in an anchor tag pointing to url

·         txt.match(RegExp) returns null if no match found

Dates

·         new Date([yyyy, mm, dd [, hh, min, ss]])

·         getFullYear()

·         toUTCString() Note: not camel cased

·         new Date() returns today’s (local) datetime

·         d.setFullYear(y,m,d) sets the date on datetime object d

RegEx

·         var s = "Hello World how are you today";
var p = /world/I;
var result = s.match(p); // returns matching text or null ("World")
var result2 = p.exec(s);  // returns matching text or null ("World")
var result3 = p.test(s);   // returns true or false (true)

?? What happens if there are multiple matches? ??

XML

http://www.w3schools.com/xml/xml_parser.asp

Load XML Doc from a string

window.DOMParser (IE9+), Microsoft.XMLHTTP ActiveXObject otherwise

var xmlDocument;

if (window.DOMParser) {

    xmlDocument = new DOMParser().parseFomString(myXml, "text/xml");

else {

    // IE8 and earlier

    xmlDocument = new ActiveXObject("Microsoft.XMLDOM");

    xmlDocument.async = "false";

    xmlDocument.loadXML(myXml);

}

Load XML Doc from a URL

XMLHttpRequest (IE9+), Microsoft.XMLHTTP ActiveXObject object otherwise.

Most browsers do not allow loading from a URL from a different domain.

var xmlHttpRequest;

if (window.XMLHttpRequest)  xmlHttpRequest = new XMLHttpRequest();

else xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");

 

xmlHttpRequest.open("GET""navigation.xml"false);

xmlHttpRequest.send();

var xmlDoc = xmlHttpRequest.responseXML;

 

Using the XML

Once the XML is loaded, it's accessed either by walking, or via getElementsByTagName.

var xmlDoc = xmlHttpRequest.responseXML;

var topics = xmlDoc.getElementsByTagName("topic");

alert("topics.length = " + topics.length);

for (i = 0; i < topics.length; i++) {

    alert("'" + topics[i].getAttribute("name") + "' has " +

          topics[i].getElementsByTagName("subtopic").length + " subtopics");

}

 

Navigation.xml

<?xml version="1.0" encoding="utf-8" ?>

<root>

  <pages>

    <page name="Javascript">

      <topic name="Sources" />

      <topic name="Stuff I Always Forget" />

      <topic name="RegEx" />

      <topic name="XML">

        <subtopic name="Load From String" />

        <subtopic name="Load From URL" />

      </topic>

      <topic name="Tricks &amp; Tricks" />

    </page>

  </pages>

</root>

 

Nodes

In Javascript XML processing, Elements, Attributes, Text, Commend and Document are all considered to be Nodes, as are 7 more that are not worth listing here.

Elements nodes can be found by walking the document, or using the getElementsByTagName method:

var firstMyTagElementInDoc = xmlDoc.getElementsByTagName("myTag")[0];
var valueOfThatTag = firstMyTagElementInDoc.nodeValue;
var firstChildElementOfThatElement = firstMyTagElementInDoc.ChildNodes[0];

One important thing: The text in the body of an element (e.g. <element>myText</element>) is not considered to be the nodeValue of that element. The XML DOM constructed by Javascript places this text in a child Text node under the Element node. The syntax to access the text is therefore actually: xmlDoc.getElementsByTagName("element")[0].childNodes[0].nodeValue == 'myText';

The properties of a node are:

·         nodeName, nodeValue

·         parentNode, firstChild, lastChild, nextSibling, previousSibling

·         collections: childNodes, attributes

Attribute can be set either by changing the attribute's nodeValue or by calling setAttribute() from the parent.

Accessing Nodes by Name

The built-in node collections (myElement.childNodes, myElement.attributes, etc) are not directly accessible by name (e.g. myElement.attributes["myAttribute"] will fail). The getNamedItem() method on node collections provides one solution (e.g. myElement.attributes.getNamedItem("name").nodeValue;, but myElement.getAttribute("name"); is simpler (if you want the attribute node rather than value, use getAttributeNode(…) instead.)

More on Text Nodes

With the exception of IE, all Javascript DOM browsers create Text Nodes for whitespace. Thus under IE:
<root>

  <hello /><!--note the two spaces before the hello element -->

</root>

root would have 1 child node, under non-IE browsers it has two (the Text node containing the whitespace and the hello Element node).

Nodes with a nodeType of 3 are Text nodes (1=element, 2=attribute, 3=text, 4=CData, etc).

Tricks and Tips

·         Action function:
function forEachCallAction(array, myAction) {
    for (var i=0;i<array.length;i++) myAction(array[i]);
}

·         Negate function:
function negate(fn) {
    return function(x) {return !fn(x);}
}

·         ‘$’ is considered a letter by JavaScript. Before jQuery monopolized it, this was cool & popular:
function $(id) { return document.getElementId(id);}

·