Javascript
{Decoded}

An E-book by
Dr. Michael Stone

(Powered by rooloose.com) ©2018
: :
| |

( JS )

Recently an iT Developer said to me that the internet was now all javascript (JS). Yet few attempt it. So it is up to a 'Newb' like me to decode this Object Orientated Language. Nearly everything JS is an Object. It is also pretty quirky! For example value null (which means zip / nada) is a defined Object; and undefined can be redefined! NaN means 'Not a Number' but is a typeof Number Object. if (x === true) true; if (x == true) Maybe true! A function is a reusable {code-block} that will be executed by an event; or when the function is called. All the above and more defines JS as a 'loose' language and once you begin coding it;   "You will love it to death".

This Book presumes you are already famliar with some HTML and CSS. We want to teach you fast and use Algebra for JS Names; as English may not be your first Lang. Algebra keeps the code short.

This Chapter 0 (intro) takes care of some of the definitions you will need as you progress. To get started skip to Chapter 1 the (basics).

Mini Calculator: JS Operators « I have pre-entered numbers. var x = 9, y = 2;. Now use the green button « (x)   (y)

(c)

(d)   (=)
Often it is about getting the Number you want. EG: ☆ Find an Odd number with x & 1; and x % 2; ☆ Round a decimal with x | 0; ☆ if x=-1; ~x = 0; "falsy". ☆ var x=9; alert( (x/2|0) === (x>>1) ); _________________________________ JS provides six primitive data types : ( see reserved word typeof ) null, undefined, (Empty) Number, String, Boolean, Symbol :: New in ECMAScript6. A Symbol is unique and immutable.

Note: ECMA Script is the same as javascript. Every year there is an update so ECMA6 == 2016. Be alert to Browser support. Symbol( ) for example will throw an error if ECMA6 is not supported!

Binary Arithmetic Operators : + addition 2 + 2 = 4; - subtraction * multiplication / division (floating-point value) % modulo (returns remainder) Unary Arithmetic Operators : + unary conversion of string to number - unary negation string to -neg number

The + operator does multi things and is described as overloaded!

A String can be numeric, '000042'. The shortest way to convert a numeric string to a number is to use + ; so (+'000042' === 42) and (-'000042' === -42). To reverse this ("0000"+42 === '000042'). Note: ('String'+ Number === String) or (Number +'' === String). More 'String' conversion. alert('1'*1 === '1'-0 && '1'-0 === '1'/1 && typeof ('1'-0) === 'number'); Notice there are Multi-Ways to (c)ast out of a (no floating point) string to Number. var x = '9', y = '2', /* x+y = '92' */ c = parseInt(x) + parseInt(y); alert(c); if ( c === -(-x-y) && c === ~~x+~~y && c === +x+ +y && c === x|0+y|0 && c === x- -y)alert(c +' is '+ typeof c); If +'String' is not numerical JS will return the reserved Number Object NaN (Not a Number). alert(+'s'); alert(1%0); alert(void 0 + 1); /* undefined+1 */ alert(NaN + 1); NaN +1 is still NaN and the only JS value that does not equal itself! As well as the above + adds Strings. 'one' + '-' + 'two'; is 'one-two'. ALSO: ++ increment ( ++n; n++; ) ++ prefix -- decrement ( --n; n--; ) postfix -- CAUTION: These in flow can be very tricky! Double check the result is what you expect. At first use n = n + 1; n = n - 1; or n + = 1; n - = 1; Assignment Operators : = assign += add and assign -= subtract and assign *= multiply and assign /= divide and assign %= modulo and assign
Comparison Operators : A Comparison returns true or false. == equal != not equal > greater than >= greater than or equal to < less than <= less than or equal to === identical (and of same type) !== not identical
Logical Operators : ! (NOT !a) unary negation. ^ (OR ^a) Exclusive OR (see Bitwise). && (AND a && b) binary conjunction. || (OR a || b) binary disjunction. X = c ? t : f; ternary (c)onditional. if (c){...} Logical reserved word if. else {...} Logical reserved word else. switch(c){case value:{...}break;} (switch API. SEE: Chapter 3; Patterns). JS short-circuit logic: a || b; When a is true, Fail b; a || Default; When a is false; do Default. a && b; When a is false, Fail b; c ? t : f; When c is true, Fail f. "truthy" / "falsy" concept Logic: The a && b; operator returns the value of the first false operand, or the value of the last operand if both or all operands are "truthy". The a || b; operator returns the value of the first true operand. In cases where neither operand is "truthy", it’ll return the last of both or all operands. Logical Operation: Native false "falsy". Strings: "", '', (any empty string). Numbers: 0 incl. +0; -0;, NaN [Not a Number]. Empty: null, undefined. Boolean: false. alert(undefined || null || NaN || '' || 0 || false); Only NaN !== NaN; 'Not a Number' NaN is never equal to NaN; but always "falsy". alert(NaN !== NaN ? true : false); ALSO: void 0 is "falsy"; as (void 0 === undefined) is true. alert(void 0 === undefined ? true : false); alert('undefined' === ''+void 0); If not "falsy"; must be "truthy". If x is a !1 value, !x is true, and !!x is false. If x is a !0 value, !x is false, and !!x is true.

Reserved Keyword typeof : typeof is used to find basic values.

Binary Bitwise Operators : & and | or ^ xor ~ Bitwise Not (inverts the bits) << shift left (zero fill at right) >> shift right (sign-propagating); copies of the leftmost bit (sign bit) are shifted in from the left. >>> shift right (zero fill at left). For positive numbers >> and >>> yield the same result. Bitwise Assignment Operators : &= and |= or ^= xor <<= shift left (zero fill at right) >>= shift right (sign-propagating); copies of the leftmost bit (sign bit) are shifted in from the left. >>>= shift right (zero fill at left). For positive numbers, >>= and >>>= yield the same result. JS Loops : A Loop is a code way to do something repeatedly. The while Loop: while ( Condition ){ loopbody }; or do while loop are the most efficient where suitable. The convention when Looping an Array or code block is to use a while or a standard for Loop. for (initial eXpression; Boolean true / false Condition; (i)ncrement Expression){ loopbody }; Notice the for LOOP is essentially: X; while ( C ) { loopbody; i;} Other Loop reserved words are break and continue.

{O}bject Literals have a for LOOP: for ("key" in Object){ loopbody };

In the Loop examples throughout this Book I have worked on keeping all parts of the Loops Short (efficient). A loop MUST END by making the condition false or break; The right kind of return will also KiLL a LOOP. You will also discover Loops can be as creative as you wish. Reserved Keyword var : A JS variable should be declared as var a var is a name / value object. In ECMA variables can be declared with let for a block level variable. var for a function level variable. or const for an immutable one. Reserved Keyword function : Functions are the most important JS code blocks and can be executed repeatedly. You can pass a function any number of values ('a0', 'a1', 'a2',...) called arguments. Arguments can be any typeof even another 'function'. (function and function literal SEE: Ch. 2 { }). Functions can return a value. JS is about writing better function(s). Use the function SYNTAX, that suits the occasion or you! Function Declaration: function f( ){ /* f scope */ } Function Literal or Named Function Expression: var fn = function( ){ /* fn scope */ }; A Function call is f( ), fn( ); Call with arguments fn('a0', 'a1', 'a2'); Function ( I.I.F.E ) Self Calling : ( do first Function ). (function(m, s, $){$=m+s;}('my',' scope')); Reserved Keyword return : JS Functions require an explicit return statement for returning the value. return ( a value) ends execution in a function and returns a value to the caller. Default value for return; is undefined. function f(x){x = 6; return;} alert(f( )); if(something)return; Can be useful! To skip the rest of a function. In most cases it will also KiLL a LOOP if inside a function! function f(x){x = 6; if (x > 5)return x; /* skip the rest */ } alert(f( )); function f(x){var i = 1; /* return KiLLs f / LOOP */ while(i++){if (i > x){ i += x; return i;}} /* skip the rest */ } alert(f(6)); Reserved Keyword this : this is the current execution context of a function (type). At first this will refer to self Browser tab / window. So ALWAYS check what this is. JS has nine built-in Constructors and the reserved word new : new Array( ), Boolean( ), Number( ), String( ), Function( ), Object( ), Date( ), Error( ), and RegExp( ). When creating values we are free to use either object (Literals or Constructors). JS (run time) mostly prefers literals; so work with literals when they are the best option. Note: Constructors are essential, but not used all the time. EG: RegExp( ) represents regular expressions, often used for pattern-matching and search-and-replace functions on text. It is best to look up what to do, as required! ^ ^ ^ ^
{ }

The way code is written is called Syntax. Over time JS language just evolves! So only a PHD would be stupid enough to describe JS Syntax. There are only a few hard and fast rules. The rest is easy to learn in practice. (1) ALL JS is Case Sensitive (a, A, b, B). (2) Use var word when declaring variables. As in var x, y = 1, z = 'zebra'; A var is scope local so you can use the same var name again in a new scope. WARNiNG: If you forget to use var in ANY scope it is always GLOBAL. w3 on JS scope. (3) Names must start with ( _ , $, a Letter ). and should NOT be JS Reserved Words (4) JS counts start 0,1,2,3 etc. (5) ' ', " ", ( ), { }, [ ], /* Open / Close */ Where " " or ' ' is String Syntax. ( ) Do first in flow. { } Code Block / Object Syntax. [ ] is Array like Syntax. /* ... */ In flow Comment. (6) ?, :, ., !, /, \, , ; c ? t : f; ternary (c)onditional. : Object Syntax var o={k:v}; . Object Syntax var o={ }; o.k=v; EG console.log(o.k); [ ].length; this. ; ! Boolean Syntax. / \ String, RegEx Syntax. , separate in flow (a, b, c, d). ; end of statement (important). (7) If your code does not run as expeced when all on one line the Syntax is wrong! // Line Comment (breaks rule 7) /* This Comment OK rule 7 */ NOTE on rule (7): Some Robots will read / revert code to a (long) one-line (string). Syntax Errors or // Line Comment will break 'strung-out' code.

Tip: The most common error in multi-line code is a line-broken, string or return (statement).

With the exception of null and undefined js Objects have Properties. See W3 Properties; Methods; Properties that contain functions are Methods of the data they belong to. E.G. 's'.toUpperCase( ) is a String Method. You can alert('Any valid Data'); and as a phone or tablet has this method we make use of it to examine Code Blocks. This may seem obvious to you but JS is scripted in English. So when you see a Method like .substring( ); it realy does mean a sub part of a string!

Consider these interactive Code blocks as a Question and Answer Quiz. Do you understand the 'WHY' of the alert( ). NOT a lot of Text from now on. As you need to read the code NOT the explantion! Tip: If you are online you can open up the W3 tryit editor or W3 tryit js String Edit and Run » any script. The Editor also works great from cache. alert("A String"); /* WoW */ alert('a string' === 'A String' ? true : false); alert('a string' === 'A String' ? !0 : !1); Comparison, returns true or false. alert('a string' === 'A String'); alert(typeof 'Hi Mia'); var s = 'roo', r = 'roo'; alert(s === r); alert('roo'.length); /* length property */ alert('roo '.length); /* space=3 */ alert('roo'['length']); /* alt. syntax */ alert('roo'.length === 'foo'['length']); var s = 'A String'; alert(s[0]); alert('A String'[2]); ''.substring( ); and ''.substr( ); Methods. var s = 'A String'; alert(s.substring(0, 1)); var s = 'A String'; alert(s.substring(2,5)); alert('A String'.substr(5)); var b = 'B52';alert(b.substr(b.length-2)); var b = 'B52';alert(b.substr(-2)); alert(('B'+52).substr(1)); alert(typeof ('B'+52).substr(1)); var b = 'B52'; alert( b[1] === '5' && b.substring(1,2) === b[1] ) ''.indexOf( ); Method / [ ? ]. alert('Hi Mia'.indexOf('Mia')); alert('Hi Mia'.indexOf('Mia',0)); alert('Hi Mia'.indexOf('Mia',3)); NB ''.indexOf( ); uses -1 for FAiL. Because, 0 is also index [0]. alert('Hi Mia'.indexOf('Mia',4)); /* (-1) Mia not found 4+ */ var p = 0, s = 'Mia is home'; p = s.indexOf('Mia'); if(p>-1){ alert('Mia found ['+p+']')}else{ alert('Mia is out '+ p);} p = s.indexOf('Lylu'); if(p>-1){ alert('Lylu found ['+p+']')}else{ alert('Lylu is out '+ p); /* -1, FAiL */ Number Logic, ~ SEE Chapter 0. var p = 0, s = 'Mia and Lylu are home'; /* Works, as only 0 is falsy */ p = ~s.indexOf('Mia'); p ? alert('Mia found ['+~p+']') : alert('Mia is out '+ ~p); p = ~s.indexOf('Lylu'); p ? alert('Lylu found ['+~p+']') : alert('Lylu is out '+ ~p); /* -1, FAiL */ alert('Hi Mia'.toUpperCase( )); alert('S'.toLowerCase( ) === 's'); var s = 'Hi'+' Mia'; alert(s); var h = 'Hi', m = ' Mia'; alert(h += m); var h = 'Hi', m = ' Mia', s = h.concat(m); alert(s); var s= ''.concat('You can ','lead a ', 'horse to water.',' But you cant ', 'make it think.'); alert(s); var s = ''.concat('You can lead ','\n', 'a horse to water. ','\n\n', 'But you cant ','\n','make it think.'); alert(s); Works by escaping with '\'. alert('\'Coo-ee!\' he said.'); alert("\"Coo-ee!\" he said."); Clean String front & back. RegEx. var S = ' A String '; S = S.replace(/^\s+|\s+$/g,''); alert('S = |'+S+'|'); A String is not ( !== ) a Number. alert(2 == '2' ? true : false); /* CAUTiON */ alert(2 === '2' ? true : false); /* OK */ var s = '2'; alert(s+s); /* '22' */ alert('2' + 2); /* 'string'+num='String' */ alert(2 + '5'); /* num+'string'='String' */ var x = 2+'5';alert(x+', '+typeof x); /* + */ BUT CAUTION as: var y = 2-'5';alert(y+', '+typeof y); /* (-) */ var y = '5'-0;alert(y+', '+typeof y); /* (-) */ var y = '5'/1;alert(y+'\n'+typeof y); /* (/) */ var y = '5'/0;alert(y+'\n'+typeof y); /* (/) */ The short way to convert a Number to a String is with +''; like so ''+n or n+''; alert('2' === 2 +'' ? true : false); The short way to convert a numeric String to a Number is with +; like so +''; alert(2 === +'2' ? true : false); alert(-2 === +'-2' ? true : false); The short way to convert a numeric String to a -Number is with -; like so -''; alert(-2 === -'2' ? true : false); var x = +'2'; if (typeof x === 'number'){alert(x);} alert((+'000042' === 42) ? !0 : !1); var y = +'42'; alert('y='+y+' is a typeof '+typeof y); var x = '2' * 5; typeof x === 'number' && alert(x); var x = '2' / 1; alert('x = '+x+' is a typeof '+typeof x); If you convert a String to Number, which is not Numerical. You will make the Number Object NaN. var y = +'s';alert(y); /* Not a Number */ Only NaN not equal to itself! var y = +'s';alert(y !== y);/* y must be NaN */

Working with Numbers. This is just like high school Math. JS Math methods are all 'class' methods. All the trigonometric functions use angles expressed in radians, not degrees or grads. For a good table of the Math Object. SEE wiki JS Syntax.

alert(2 * 3 + 5); /* left to right 2x3 add 5 */ alert(2 * (3 + 5)); /* ( do First ) */ alert(2 * (3 + 5)/2); /* ( do First ) */ var x = 0; x = x + 1; alert(x); var x = 0; x += 1; alert(x); var x = 0; x++; alert(x); Number.toFixed( ); Method. (Rounds UP and returns a string). var p = Math.PI; alert(p +'\n'+p.toFixed(4) +'\n'+p.toFixed( ) +'\n'+typeof p.toFixed( )); var x = 5.000678678; alert(x.toFixed(8) +'\n'+x.toFixed(2) +'\n'+x.toFixed(0) +'\n'+typeof x.toFixed(8)); _______________________ [ Preview next Chapter (2) (A)rray ] One of the first Number things we need to learn is the LOOP. I have made a Default loop that should fit most situations. 1. Start with a (n)egative (n)umber. n = -(Loop Length) +1; to loop forwards. EG. (-3 to 0) length = 4; 2. do; while LOOP always executes once. 3. Here is the flow: 1st lp c = n = -3; {i=0; i+=1;} n+=1; 2nd lp c = n = -2; {i=1; i+=1;} n+=1; 3rd lp c = n = -1; {i=2; i+=1;} n+=1; 4th lp c = n = 0; {i=3;} (c)ondition = 0 === false; END. With this pattern we can work with more than one (i)ndex if required. Or kill the loop by return 0; (function(A){ /* n = -(Loop Length) +1 */ var c = 0, i = 0, n = -3; function lp( ){ A[i] = i; i += 1; /* do more with (i)ndex */ return n;}do{c=lp(n)}while(n+=1,c); alert(A);}( [ ] )); When programing Math the rule is to check that the answer is always what you expect. Take special care with ++i; i++; --i; i--; (see Ch. 0) which are tricky in flow. Also large &/or irrational numbers! Try Mini Calculator Chapter 0 (intro). ^ ^ ^ ^
[ ]

o = { };
a = [ ]; One of the best things you can do is to make ordered lists... Programing Languages are built around ordered lists. In JS ordered "(k)ey" slots declared as above are called Object Literals. !IMPORTANT: By definition JS Object Literal code is always an un-ordered list. var o = {a:0, b:1, c:2, d:3}; alert(o.c); var o = {a:0, b:1, c:2, d:3};alert( o['c'] ); var o = {a:'r',b:'s',c:'v',d:'p'};alert( o['c'] ); Zero [index] Number slots declared as above are called (Object) Array Literals. By definition an Array Literal is ordered. var a = [0, 1, 2, 3]; alert( a[3] ); var a = ['a', 'b', 'c', 'd']; alert( a[3] ); A function is also an Object. So a function Literal looks like: var fn = function( a, b, c ){a = 0;}; a, b, c are the parameters (name). CALL: fn( 0, 1, 2 ); 0, 1, 2 are the arguments (value). parameters have the default value undefined. Which is "falsy". (function(n, u){ alert('n = '+n+'; u = '+u);}(88)); (function(a, b, c, d){ /* c, d undefined */ c = d; alert(c);}(0, 1)); (function(a, b, c, d){alert(b);}(0, 1, 2, 3)); (function( ){alert( arguments[1] );}(0,1,2,3)); You should define stuff when you can. Here c, d are given the value of a (0); (function(a, b, c, d){c=d=a; alert(c);}(0, 1)); (function(a, b, c){ var q = (arguments[0] === a); q&&alert(q);}(0, 1, 2)); (function(a, b, c){ alert(arguments[2] === 8);}(0, 1, 8)); {O}bject, [A]rray Literals and arguments slots can be any Native data typeof. Even another function. (function( ){ alert(arguments[2]+', '+arguments[5].k);} ( !0, 1, 'jah', null, void 0, {k:'liv'}, [ ] )); (function(f){var x = f( );} /* f call( ) */ (function( ){alert('a function');})); To declare empty Object Literals; do it like so: var o = { }, a = [ ]; (function( ){var o = { }, a = [ ]; o['n'] = 'Mia'; a[0] = 24; alert(o.n +' age '+a[0]); }( )); .... OR (function(o, a){ o.n = 'Mia'; a[0] = 24; alert(o['n'] +' age '+a[0]);}( { }, [ ] )); Explore; some Literals SYNTAX. (function(o){o.f( );} /* { } Syntax */ ( {n:'Mia', a:25, f:function( ){ alert(this.n+' age '+this['a']);}} )); (function(a){a[2]( );} /* [ ] Syntax */ ( ['Mia', 25, function( ){ alert(this[0]+' age '+this[1]);}] )); Inner and outer functions and this. For more on this SEE: Chapters 0, 4. (function(o){o = {n:'Mia', f:function(s, io){ s=this; io = {a:26, ifunc:function( ){ alert(s.n+' age '+this.a);}};io.ifunc( ); alert(this.n);}};o.f( );}( )); /* { } Syntax */ .... OR (function(o){o.f();} ( {n:'Mia', f:function(s, io){ s=this; io = {a:26, ifunc:function( ){ alert(s.n+' age '+this.a);}}; io.ifunc( ); alert(this.n);}} )); /* { } Syntax */ (function( ){['Mia', function(s){ s=this; [26, function( ){ alert(s[0]+' age '+this[0]);}][1]( ); alert(this[0]);}][1]( );}( )); /* [ ] Syntax */

Object, Array Literals and Function arguments can be useful for code organisation. SEE: patterns Chapter 4.

Like 'S'tring, [A]rray and arguments have a length property. alert( [0,1,2].length === [0,1,2]['length'] ); As the first slot is [0]; the length is always the last slot number +1. (function(a){alert(a.length; alert(arguments.length));; }( [0, 1, 2, 3] )); (function(a){alert(a['length']); alert(['arguments']['length'); }( [0, 1, 2, 3] )); (function(a, b, c){ /* a,b,c are params */ alert(arguments.length);}( )); CAUTION: Only [A]rray will let you hard code [ ].length; or [ ]['length']; You can code arguments.length = L; or "".length = L; But to NO Effect! (function(a, b, c, d){arguments.length=2; alert('L = '+arguments.length); alert('c = '+c); /* But values still there! */ alert('d = '+d);}(0, 1, 2, 3)); /* L = 4 */ CAUTION: arguments are only [A]rray like. If you need to, this line will make arguments a true [A]rray. (function( ){ var A = [ ].slice.call(arguments); /* [ ].slice */ alert('A = ['+A+']');}('a', 'b', 'c', 'd')); An Object Literal has NO length property. But it has a dedicated for in Loop. SEE: JS Loops Chapter 0. So we can calculate (o) or (k).length (oL). NOTE: ECMA5 can do Object.keys(o).length; ECMA5 More in Footer Chapter 5. (function(o, oL, k){for(k in o)oL+=1; alert(arguments.length+'; oL = '+oL); }( {a:'a', b:'b', c:'c', d:'d'}, 0)); (function(o, oL){ /* ECMA5 */ oL = Object.keys(o).length || 0; alert(arguments.length+'; oL = '+oL); }( {a:'a', b:'b', c:'c', d:'d'} )); When you’re not sure about the contents of the object (and its prototype chain), as in imported from somewhere else; you’re safer just adding the hasOwnProperty( ) check. (function(o, k){var oL = 0, rP = function(i, h){h = 'hasOwnProperty'; return o[h](i);}; for(k in o)rP(k)&&(oL+=1); alert(arguments.length+'; oL = '+oL); }( {a:1, b:2, c:3, d:4} )); Cache the method as (P) and call it. For better performance. (function(o, k){ /* Object.prototype */ var oL = 0, P = { }.hasOwnProperty; for(k in o)P.call(o, k)&&(oL+=1); alert(arguments.length+'; oL = '+oL); }( {a:1, b:2, c:3, d:4} )); (function(o, K, i){for(K[i++] in o); alert(arguments.length+'; K=['+K+']'); }( {a:0, b:1, c:2, d:3}, [ ], 0)); (function(o, V, i, k){for(k in o)V[i++]=o[k]; alert(arguments.length+'; V=['+V+']'); }({a:0, b:1, c:2, d:3}, [ ], 0));

WORKiNG With Object [A]rray. And thinking about JS Engine performance.

As JS is loose typed, [A]rray (v)alues can be any typeof or mixed. However, with performance in mind a pre-allocated integer Array is best. Default: var A = [0, 0, 0, etc, 0, 0]; TRY to avoid mixed typeof Arrays and that includes empty, undefined, Slots! As you can imagine, void 0, null or a Boolean are also weak values! NaN could be OK as it is a typeof Number. Fill all [A]rray Length with a (v)alue. (function(A){var i = 0, v = 0, L = 88; while(i<L)A[i] = v, ++i; alert(A);}( [ ] )); /* v = 0 */ (function( i, L, v){var A = [ ]; while(i<L)A[i] = v, ++i; alert(A); alert(A[0] !== A[1]);}(0, 8, NaN )); (v)alue = [i]ndex; / Method: [ ].slice( ); (function( i, L, s0, s1, s2){var A = [ ]; while(i<L)A[i] = i, ++i; alert(A); a0 = A.slice(-20); alert(a0); a1 = A.slice(0,20); alert(a1); a2 = function q(x, n){ return A.slice(x,(x+n))}(20, 10); alert(a2); }(0, 42)); Fibonacci numbers sum series (function(L, A, R){ L = +prompt('Enter length (L)', L)||1; L > 42&&(L = 42); A = [ ]; R=function(r){ /* By Recursion */ r < L&&(A[r]=r<=1 ? r : A[r-2]+A[r-1],R(r+1))}; R(0); alert(A); }(20)); (function(L, A, i){ L = +prompt('Enter length (L)', L) || 1; L > 42&&(L = 42); A = [ ]; for(;i<L;i=i+1)A[i] = i<=1?i:A[i-2]+A[i-1]; alert(A); }(9)); Lucas Sum series. By Recursion. (function(L, A, R){ L = +prompt('Enter length (L)', L) || 1; L > 42&&(L = 42); A=[ ]; R = function(a, b, r){ /* By Recursion */ r < L&&(A[r] = a, R(b,a+b,r+1))};R(2,1,0); alert(A); }(6)); (function(L, A, i){ L = +prompt('Enter length (L)', L) || 1; L > 42&&(L = 42); i = 0; A = [ ]; while( i<L )A[i] = i<1?2: i == 1?1:A[i-2]+A[i-1],i = i+1; alert(A); }(9)); (function(A, r){ /* random Array value */ r = A[Math.random( )*A.length | 0]; alert(r);}( ['a', 'b'] )); (function(A){ /* random Array value */ alert( A[Math.random( )*A.length | 0] ); }( [0, 1, 2, 3] ));

There are plenty of Array Methods. Try to understand exactly what they DO and COST (performance). Often you can write your own.

Better than [ ].push(3); (function(A){A[A.length] = 3;}( [0, 1, 2] )); A cool thing to do is to make your [A]rrays an 'oversize' Stack. You can then perform Methods like push, pop, shift, unshift, without much performance cost! You make your own internal Lengths. (function(A, pop){var aL = 0; A[aL++] = 1; alert(A+' aL='+aL); aL > 0&&(pop = A[--aL]); alert(A+' aL='+aL+' p='+pop); }( [0, 0, 0, 0, 0] )); Add 'v'alue to front[0]: Like [ ].unshift( ); (function(A){var i = A.length, v = 'v'; while(i)A[i] = A[i-1], i--; A[0] = v; alert(A);}( ['a', 'b', 'c'] )); Add one 'v'alue to Array at inde[x]: Like [ ].splice( ); (function(A, x){var i = A.length, v = 'v'; while(i-->=x)A[i+1] = A[i]; A[x] = v; alert(A);}( ['a', 'b', 'c'], 0)); /* [0] */ (function(A, x){var i = A.length, v = 'v'; while(i-->=x)A[i+1] = A[i]; A[x] = v; alert(A);}( ['a', 'b', 'c'], 2)); /* [2] */ Remove one item (value) by [i]ndex; (function(A, i){var L = A.length; if(i<L){ while(i<L)A[i] = A[i+1], i++; --A.length;} alert(A);}( ['a', 'b', 'R', 'd'], 2)); /* [2] */ Find (v)alue (i)ndex: Like [ ].IndexOf( ); from [0]. (function(A, v, n){var i = n, L = A.length; for(;i<L;++i)A[i] === v?(n=i, L=0):n=-1; alert(n);}(['a', 'b', 'c', 'd'], 'd', 0)); (function(A, v, n){var i=n,L=A.length; for(;i<L;++i)A[i] === v?(n=i, L=0):n=-1; alert(n);}( ['a','b','c','d'], 'z', 0)); OR .... (function(A, v, n){var j, i = n; for(; j=A[i+=1];)j === v &&(n=i, i=NaN); alert(n);}( ['a', 'b', 'c', 'c'], 'c', -1)); (function(A, v, n){var j, i = n; /* fail=-1 */ for(; j=A[i+=1];)j === v &&(n=i, i=NaN); alert(n);}( ['a', 'b', 'c', 'c'], 'z', -1)); Find: Like [ ].lastIndexOf( ); from [last]. (function(A, v){var i = A.length; while(i--)if(A[i] === v)break; alert(i);}( ['b', 'b', 'c', 'd'], 'b')); (function(A, v){var i = A.length; while(i--)if(A[i] === v)break; alert(i);}( ['b', 'b', 'c', 'd'], 'x')); /* fail=-1 */ [ ].reverse( ); Array Method. (function( ){alert( [0,1,2,3].reverse( ) );}( )); Arrays are often used to manipulate Strings / Number Strings. "".split(v); splits to [A]rray. [ ].join(v); joins to "". Where v is some (v)alue. EG: (function(s){s = s.split('').join('-'); alert(s);}('COOEE')); You can re-order an Array. [ ].sort( ); Method API. [ ].sort([compareFunction]); SYNTAX. (function(A){A.sort( ); alert(A); }( ['Sun','Smith','Sims','Smyth','Smith'] )); (function(A){A.sort(function(a, b){ return a<b?-1:a==b?0:1}); alert(A); }( ['Sun','Smith','Sims','Smyth','Smith'] )); The sort API will auto call until the compareFunction or Default is done; a, b is just convention. It is better to hard code [ ].sort(function(a, b){Your Code}); as Browser algos may differ. (function(A){ A.sort( ); alert(A);}( [3, 0, 88, 3, 42] )); (function(A){A.sort(function(a, b){ return a - b}); alert(A);}([3, 0, 88, 3, 42])); NB Method: splice is NOT slice; splice is clever but has a big COST. You can use splice.... then later work on replacing it with lighter code! (function(a0, a1){var L = a0.length; a0.splice(L/2, 1, a1.join(','), a0[L/2]); alert('a0=['+a0+'];');}( ['a', 'b'], ['x', 'y'] )); ECMA3 apply( ); to the rescue! (function(a0, a1){ [ ].push.apply(a0, a1); alert('a0 = ['+a0+'];');}( ['a', 'b'], ['x', 'y'] )); (function(a0, a1){var a2 = [6, 7, 8], cA = function( ){ return [ ].concat.apply([ ], arguments);} a0 = cA(a0, a1, a2); alert('a0 = ['+a0+'];');}( [0, 1, 2], [3, 4, 5] )); (function(A){var x = Math.max, X = x.apply(0, A), n = Math.min, N = n.apply(0, A); alert(X+' > '+N);}( [0, 4, 88, -99] )); ^ ^ ^ ^
( )

typeof is a JS reserved word that is hardly used in modern JS. However, it is great to teach us SYNTAX and Object Name / Type. Tip:- JS is NOT a typed Language. But we should write it as if it is and favour the smallest typeof to help out the JS engine! Number is the 'lightest' typeof. (function( U, sy ){var p = [ 'undefined', /* Default Value */ ''+void 0, /* Proxy for undefined */ 'boolean', /* Chapter 0 (intro) */ 'string', /* Chapter 1 (basics) */ 'number', /* Chapter 1 (basics) */ 'function', /* Chapter 0, 2, 3 */ 'object' /* Chapter 0, 2, 3 */ ''+void 0, /* ECMA6 Symbol Ch. 0 */ ], fn = function( ){ }; if(typeof Symbol !== p[7]){ p[7] = 'symbol'; sy = Symbol( );}; typeof U === p[0] && typeof U === p[1] && typeof !1 === p[2] && typeof '' === p[3] && typeof Math.random( ) === p[4] && typeof fn === p[5] && typeof null === p[6] && typeof sy === p[7] && alert(p.join('\n'));}( )); More Object, Object; (function( ){var o = 'object', y = [null, { }, [ ], new Date( ), /regex/]; typeof y[0] === o && typeof y[1] === o && typeof y[2] === o && typeof y[3] === o && typeof y[4] === o && alert(JSON.stringify(y).replace(/,/g,',\n')); }( )); (function(w,t,l,u, s,n,b,o,a, f,m){ var x, r = ' &raquo; ', sa = [ /* build string sa=[ ].join( ); */ ' 0 typeof w = '+typeof w+''+r+w, ' 1 typeof t = '+typeof t+''+r+t, ' 2 typeof l = '+typeof l+''+r+l, ' 3 typeof u = '+typeof u+''+r+u, ' 4 typeof s = '+typeof s+''+r+s, ' 5 typeof n = '+typeof n+''+r+n, ' 6 typeof b = '+typeof b+''+r+b, ' 7 typeof o = '+typeof o+''+r+o.k, ' 8 typeof a = '+typeof a+''+r+a[0], ' 9 typeof f = '+typeof f+''+r+f( ), '10 typeof m = '+typeof m+''+r+m ].join('\n'); /* Some Conditions? */ if(x===u && typeof f==='function')x=sa; alert(x); }(this, document, null, void 0, 'coo', 8, !0, {k:'roo'}, ['foo'], function(y){y = 3;return y;}, name)); Lots of 'Duck Typeing'. To make a better typeof / alert( ); (function(l,u, s,n,N,b,o,a, f,m){ var s1=' str ', D=Date( ), Dn=+new Date( ); /*Q*/ function Q(q){var v=' &raquo; ', t=q==null?q+='':typeof q, x=q.length,l='.length=', O=t=='string'?t+l+x+v+'|'+ q.split(/[ \u00A0]/).join('(+)')+'|': t=='object'?x?'[ ]'+l+x+v+'['+q+']': '{ }.keys='+Object.keys(q).length+ v+JSON.stringify(q):t+v+q; return O};/* or alert(O); */ alert( [ Q(l),Q(u),Q(s),Q(n),Q(N),Q(b),Q(o),Q(a), Q(f),Q(m),Q(s1),Q(D),Q(Dn)].join('\n')); }(null,void 0,'coo',8,NaN,!0, {k0:'roo',k1:'moo'},['boo','foo'], function(y){y=3;return y;}, name)); .... and again T(q); Utility fn. Tryit: Change return O; to alert(O); examine any Obj. by call; T(something); OR bulk 'tryit' as below. (function(l,u, s,n,N,b,o,a, f,m){ var s1=' str ', D=Date( ), Dn=+new Date( ); /*T*/ function T(q){ var O,y={ }.toString.call(q); y=y.slice(y.indexOf(' ')+1,-1); O=y+' &raquo; '+(y=='String'?'|'+ q.split(/[ \u00A0]/).join('(+)')+'|': y=='Object'?JSON.stringify(q):q); return O;}/*or alert(O); */ alert([ T(l),T(u),T(s),T(n),T(N),T(b),T(o),T(a), T(f),T(m),T(s1),T(D),T(Dn)].join('\n')); }(null,void 0,'coo',8,NaN,!0, {k0:'roo',k1:'moo'},['boo','foo'], function(y){y=3;return y;},name)); X-Browser ['width, 'height'] can be a pain. - Patterns to the rescue. This works as it skips over (undefined). (function(w, t, f){ f = function(E, a){ E = t.documentElement; a = [ w.pageXOffset || E.scrollLeft || t.body.scrollLeft || 0, w.pageYOffset || E.scrollTop || t.body.scrollTop || 0]; alert(a[0]+'px, '+a[1]+'px');}( ); }(this, document)); This way skips over (falsy) and finds the max Number, Which is more solid. "Your scroll Position is:" (function(w, t, f){ f = function(E, a){ E = t.documentElement; a = [ Math.max( w.pageXOffset, E.scrollLeft, t.body.scrollLeft || 0), Math.max( w.pageYOffset, E.scrollTop, t.body.scrollTop || 0)]; alert(a[0]+'px, '+a[1]+'px');}( ); }(this, document)); "Your scrollWidth, Height is:" (function(t, f){ f = function(E, a){ E = t.documentElement; a = [ Math.max( E.scrollWidth, E.offsetWidth, t.body.scrollWidth, t.body.offsetWidth, t.body.clientWidth || 0), Math.max( E.scrollHeight, E.offsetHeight, t.body.scrollHeight, t.body.offsetHeight, t.body.clientHeight || 0)]; alert(a[0]+'px, '+a[1]+'px');}( ); }(document)); "Your View Port Size is:" (function(w, t, f){ f = function(E, a){ E = t.documentElement; a = [ Math.max( w.innerWidth, E.clientWidth || 0), Math.max( w.innerHeight, E.clientHeight || 0)]; alert(a[0]+'px, '+a[1]+'px');}( ); }(this, document)); Module SYNTAX. (function( ){ /* { } SYNTAX */ function sO(s, o){ o = { a:function( ){return 'a/ 0'}, b:function( ){return 'b/ 1'}, c:function( ){return 'c/ 2'}, D:function( ){return 'D/ Default'}}; return (o[s] || o['D'])( ); }; alert( [ sO('a'),sO('b'), sO('c'),sO('doh')].join('\n')); }( )); (function( ){ /* [ ] SYNTAX */ function aO(n, a){ a = [ function( ){return n+'/ Default'}, function( ){return n+'/ 1'}, function( ){return n+'/ 2'}, function( ){return n+'/ 3'}]; return (a[n] || a[0])( ); }; alert( [ aO(1),aO(2),aO(3), aO(-1),aO('doh')].join('\n')); }( )); /* a[0] chosen as natural Default */ (function(c, q){q=c? function(a){return c+a;}(' / Y'): function(a){return c+a;}(' / N'); alert(q);}(!0)); /* IIFE(s) */ ;'use strict';(function(w, c, q){q = c? function(a){return c+a;}(' / Y'): function(s, a){alert( s === w ); return c+a;}(this,' / N'); alert(q);}(this, !1)); /* IIFE(s) */ (function( ){ /* IIFE(s) */ function iO(c, q){return q = c==3?function(z){return c+z}(' z'): c==2 || c=='r'?function(y){return c+y}(' y'): c==1?function(x){return c+x}(' x'): function(d){return c+d}(' Default'); }; alert( [ iO(1),iO(2),iO('r'),iO(3), iO(-1),iO('doh')].join('\n')); }( )); The switch js API is great for a start. It is easy to follow: (function( ){ function sS(c){switch(c){ case 0:{return 0}break; case 'roo':{return 'roo'}break; case 1:case 2:{return '1 / 2'}break; default:{return 'D'}break;} } alert( [ sS(0),sS('roo'),sS(1),sS(2), sS(-1),sS('doh')].join('\n')); }( )); (function(oQ){ oQ=function(q){var a = function( ){return 'Animal'}, m = function( ){return 'Mineral'}, v = function( ){return 'Vegan'}, D = function( ){return 'Default'}, o = {cat:a, roo:a, carbon:m, 'salt peter':m, cabbage:v, carrot:v}; return (o[q] || D)( ); }; alert( [ 'cat is '+oQ('cat'), 'roo is '+oQ('roo'), 'carbon is '+oQ('carbon'), 'salt peter is '+oQ('salt peter'), 'cabbage is '+oQ('cabbage'), 'carrot is '+oQ('carrot'), 'doh >> '+oQ('doh')].join('\n')); }( )); (function( ){ function aQ(q){var n = ~[ 'Tom', 'Dick', 'Harry', 'Lexi', 'Lylu', 'R2 D2', 'C'+2e3].indexOf(q)*-1, s= n>5?n+'. Droid': n>3?n+'. Female': n>0?n+'. Male' : n+'. 0/ Alien'; return s;}; alert( [ 'Tom is '+aQ('Tom'), 'Dick is '+aQ('Dick'), 'Harry is '+aQ('Harry'), 'Lexi is '+aQ('Lexi'), 'Lylu is '+aQ('Lylu'), 'R2 D2 is '+aQ('R2 D2'), 'C'+2e3+' is '+aQ('C'+2e3), 'Zorg ?: '+aQ('Zorg')].join('\n')); }( )); Force Function call order. (function( ){var s = '', _0 = function( ){s +='#0 | ';}, _1 = function( ){s +='#1 | ';}, _2 = function( ){s +='#2 ; ';},A=[_0,_1,_2]; while(A.length)A.shift( ).call( ); /* shift( ) */ alert(s+A.length+' is A.length');}( )); Date Stamp Pattern: (function(){var D = new Date(), d = function(n, o, k){o = {Sun:0, Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6, Jan:7, Feb:8, Mch:9, Apr:10, May:11, Jun:12, Jul:13, Aug:14, Sep:15, Oct:16, Nov:17, Dec:18}; for (k in o)if (o[k] == n)return k;}, p = ''.concat(d(D.getDay( )), ': ', D.getDate( ), '-', d(D.getMonth( )+7), '-', D.getFullYear( )); alert(p);}( )); Numbers: Native sort / shuffle. a » a (sorted) » a (shuffled) (function( ){ /* (a)ny [ ] */ var a = [1, 0, 7, 4, 8, 5, 6, 3, 9, 2]; /* Like insertion Sort algo. */ function iS( ){var t, j, i=0, L=a.length; for(;i<L;++i){t = a[i]; j = i-1; while( j>=0 && a[ j]>t)a[ j+1] = a[ j], j--; a[ j+1] = t} return a; } alert(iS(a)); /* Like Fisher Yates Shuffle algo. */ function fY( ){var t, i, j=a.length; while( j>1)i=Math.random( )*j--|0, i!=j && (t=a[ j],a[ j]=a[i],a[i]=t); return a; } alert(fY(a)); }( )); Literals { }; and [ ]; are the basis for JSON, which is a simple notation that uses JS-like syntax for data exchange. (function( ){var book = { name: 'JS Decoded', author:{first:'Michael', last:'Stone'}, year: 2018, chapters:['intro', 'basics', '{ }; [ ]; Literals', 'Patterns', 'Mini-Projects', 'Footer']}; alert( [ book.name, book.author.last, book.year, book['chapters'][0], book['chapters'][2], book['chapters'][4] ].join('\n'));}( )); (function(o){var oJs = JSON.stringify(o), /* ECMA5 */ oJp = JSON.parse(oJs), Q = JSON.stringify(oJp); Q === oJs && alert(Q); }( {name: 'JS Decoded', author:{first:'Michael', last:'Stone'}, year: 2018, chapters:['intro', 'basics', '{ }; [ ]; Literals', 'Patterns', 'Mini-Projects', 'Footer']} ));

AJAX is just a data exchange process: 1. An event occurs: onload, onclick or something creative like onerror. 2. JS makes on(1) an Object that sends a request to a web server ». 3. The server must have a program to processes and respond to that request. 4. JS reads the responce and updates the action. w3=tryajax_first w3=tryajax_callback

Unlike other Code Languages JS has no class statement. JS has Constructors. Constructors can be used to make multi similar objects with the same properties and methods. It is considered good practice to name Constructor Functions with an upper-case first letter. Most JS in-built Constructors (Chapter 0) are scope-safe. They use a pattern to see if the Constructor Function is called with new or not. ;'use strict';(function( ){ var C_list = function(n, a){ var s = this; if(!(s instanceof C_list)){ return new C_list(n, a);} s.name = n; s.age = ' ('+a+')'; }, g0 = C_list('Ami', 24), g1 = C_list('Mia', 25), b0 = C_list('Tom', 26), b1 = C_list('Max', 27); C_list.prototype.fn = function(s){ s = this; return (s.name + s.age)}; alert( [g0.fn( ), g1.fn( ), b0.fn( ), b1.fn( )].join('\n'));}( )); There are many ways in JS to define Objects. (no new or this) (function( ){ var oO = function(n, a, o){ o = {name:n, age:' ('+a+')', P:function( ){return (o.name + o.age)}}; return o.P( );}, g0 = oO('Ami', 24), g1 = oO('Mia', 25), b0 = oO('Tom', 26), b1 = oO('Max', 27); alert( [g0, g1, b0, b1].join('\n'));}( )); ECMA5 Object.create( ); Method. (function( ){ var oO = function(n, a){ var myp = {P:function (s){s = this; return (s.name + s.age);}}, oc = Object.create(myp, { name:{value:n}, age:{value:' ('+a+')'}}); return oc.P( );}, g0 = oO('Ami', 24), g1 = oO('Mia', 25), b0 = oO('Tom', 26), b1 = oO('Max', 27); alert([g0, g1, b0, b1].join('\n'));}( )); If any of the above 'modules' need to comunicate via the 'Global'. JS convention is that it should be some *distictive* Name. One name is all we need to pass stuff into our module. Use the { }, [ ] or function Literal that suits you. As in some of the above examples, (w)indow is hard coded by this. ;'use strict';(function(w, l){ function f(y){alert(y);} w._roo_GLOBE = {fn:function(o){f(o)}}; w['_raa_GLOBE'] = [function(a){f(a)}]; f(l); /* inner call = null */ }(this, null)); /* end Module */ _roo_GLOBE.fn('roo'); /* { } SYNTAX */ _raa_GLOBE[0]('raa'); /* [ ] SYNTAX */ NOTE: This is an example only. The alerts are simulated; in scope. ^ ^ ^ ^
! !



<!DOCTYPE html><html>
<head><meta charset=utf-8 />
<style type="text/css">*{margin:0;padding:0}
body{background:tan}
#Cc{display:block;white-space:normal;text-align:center}
#c12,#cZ,#c24{font-family:sans-serif;margin-top:9px;background:#22313F;
 border-radius:18px;padding:4px 12px 0 12px;text-shadow:-2px -2px #aaa;
 -webkit-text-shadow:-2px -2px #aaa;-moz-text-shadow:-2px -2px #aaa}
#c12{font-size:66px;color:#336E7B}sup{font-size:25px !important}
#cZ{font-size:22px;padding:8px 12px 5px 12px;color:purple}
#c24{font-size:58px;color:#96281B}
</style><title>_</title></head>
<body>
<span id="Cc">
<button id="c12">12</button><br>
<button id="cZ">M</button><br>
<button id="c24">24</button></span>
<script>'use strict';
(function(t, G, tH){
var _ = function(I){
return t.getElementById(I)},
X = _('c24'),Y=_('c12'),
Z = _('cZ'),Q=_('M0'),
N = N||+new Date( ),b=' BOOK',
T = function( ){
var S, M, H, D=new Date( ),
f = function(a,b){
return a>9?a:b?a:'0'+a},
s = f(D.getSeconds( )),
m = f(D.getMinutes( )),
h = D.getHours( ),p,z,
n = function(o,v){o.innerHTML=v};

/* 24 hr clock */
n(X,[f(h,1),m,s].join(':'));
/* 12 hr clock */
p = h>11?'P':'A';
h = h>12?h-12:h?h:12;
n(Y,['<sup>'+p+'M </sup>'+h,
m].join(s&1?': ':' :'));

/* BOOK Open Timer */
S = (+D-N)/1e3; M = S/60|0;
M>59&&(H=M/60|0, M = f(M-(H*60)));
S = f(S%60|0);
z = M+' min. '+S+' secs';
z = H?H+' hr. '+z:z;n(Z,z);/* / */
tH = setTimeout(T, 999);}
/* Events: (K)ill; (C)lock; */
function K( ){t.title = '.{js}'+b;
G = 1;clearTimeout(tH)}
function C( ){Q.checked&&G?(G=0,
t.title='.js'+b,T( )):K( )}
onload=t.focus=onfocus=Q.onclick=C;
onunload=t.blur=onblur=K;
}(document, 1));
</script></body></html>

Every opportunity is taken to 
(K)ill the Clocks Handle (tH).
t.title='.{js} BOOK'; is stop.

Card Game (module) Made Easy.
DEAL »
<!DOCTYPE html><html>
<head><meta charset=utf-8 />
<style type="text/css">*{margin:0;padding:0}
body{background:tan}
#cD,#SD{font-weight:600;font-family:sans-serif;}
#SD{margin-left:20px;font-size:25px}
#cD{line-height:48px;margin:9px;font-size:38px;
  cursor:pointer;border-radius:0 none;overflow:hidden;
  width:210px;height:120px}
</style><title>CARDS</title></head>
<body>
<span id="SD">DEAL &raquo;</span><button id="cD">CARDS</button>
<script>
(function(a, b){var n = 0,
I = document.getElementById('cD')||null;
function E(i,j,t,r,C,S){var nD=2,
  d=i=j=t=r=0, q = 52*nD,  /* set nD */
  M = Math.random( );
if(!n){while(nD--)for(j=52;j--;)a[d++]=j;
j = q; while(j>1)i=M*j--|0,
i!=j&&(t=a[j],a[j]=a[i],a[i]=t);
/* r cut */ j=q/2+9;i=q/3;
r = (M*(j-i)+i)|0;
b = a.slice( );i=0;while(i<q)b[i]=
i<r?a[q-r+i]:a[i-r],++i; alert(b);}
d=b[n];t=d%4;d-=t;d=(d/4)+1;
C = d>12?'K':d>11?'Q':d>10?'J':d>1?d:'A';
S = t>2?'&spades; ':t>1?'&hearts; ':
	t?'&diams; ':'&clubs; ';
I.style.color=t&&t<3?'#c00':'#000';
I.innerHTML='<u>'+(n+1)+'</u><br>'+S+C;
n=++n>q-1?0:n} /* n==0?shuffle:n */
I.onclick=E}([ ]));
</script></body></html>

Note: Card Deck(s) are shuffled 
and Cut. To copy the physical way.

Sort and Toggle a list, is a common task. Here is pattern for the job.
«
<!DOCTYPE html><html>
<head><meta charset=utf-8 />
<style type="text/css">*{margin:0;padding:0}
body{background:tan}
.aR{display:block;width:280px;font:600 21px sans-serif;color:#030;margin:0 auto;}
#R0,#R1{font-size:14px;font-weight:600;background:#000;color:#ddd;padding:5px 24px;margin:9px 9px 0 0;}
</style><title>Sort Race</title></head>
<body>
<span id="aR" class="aR"></span><span class="aR"><button id="R0">Horse^</button><button id="R1">Price^</button>&laquo;</span>
<script>
(function(_, h, $){
function sA( ){var A = [
{h:'Phar Lap', $:6},
{h:'Sub Zero', $:8.8},
{h:'Americain',$:6.06},
{h:'Kiwi', $:8.81}], L = A.length,

u = function(v, z, s){
z = z||-1; s = v?'$':'h';
return function(a, b){
a = a[s]; b = b[s];
return (a<b?-1:a==b?0:1)*z}},

k = [ ], q = +this.id[1]||0, i=0;
A.sort(q?u(q, $^=1):u(q, h^=1));
while(i<L)k[i] = '<li>'+A[i].h+
' = $'+(+A[i].$).toFixed(2),i++;
_('aR').innerHTML= k.join('')}
_('R0').onclick=
_('R1').onclick=sA; sA( );}(
function(I){return (
document.getElementById(I))}));
</script></body></html>

Change id by numbers (pattern).
Hello
MiA
LYLU
« «
<!DOCTYPE html><html>
<head><meta charset=utf-8 />
<style type="text/css">*{margin:0;padding:0}
body{background:tan}
#E{display:block;width:240px;border:6px solid #000;font-weight:800;margin:16px auto 0 auto;
height:70px;line-height:70px;font-size:40px;overflow:hidden;text-align:center}
#dT{display:block;width:330px;white-space:pre;margin:0 auto;}
.hD{font-size:14px;font-weight:600; background:#000;color:#ddd;margin:4px;padding:4px 9px}
.hD,#E{font-family:sans-serif;}
</style><title>id-change</title></head>
<body>
<span id="E">Hello<br />MiA<br />LYLU</span><span id="dT">
<button class="hD">E, 'teal', 0</button><button class="hD">E, 'indigo', 0</button> &laquo;
<button class="hD">E, 'pink', 1</button><button class="hD">E, '#ffa', 1</button>
<button class="hD">E, 'green', 2</button><button class="hD">E, 'red', 2</button>
<button class="hD">E, 'double', 3</button><button class="hD">E, 'ridge', 3</button>
<button class="hD">E, '1', 4</button><button class="hD">E, '0.5', 4</button><button class="hD">E, '0', 4</button>
<button class="hD">E, 'Cooee&lt;br>ROOJA&lt;br>ROOKA', 5</button>
<button class="hD">E, 'Hello&lt;br>MiA&lt;br>LYLU', 5</button>
<button class="hD">E, 0, 6</button><button class="hD">E, 70, 6</button><button class="hD">E, 140, 6</button> &laquo;</span>
<script>
(function(t){
var g = 'getElementById',
E = t[g]('E'),
X = t[g]('dT'),

rE = function(i){
var e = i>0?E:E, n = [
0,0,
1,1,
2,2,
3,3,
4,4,4,
5,5,
6,6,6][i], v = [
'teal','indigo',
'pink','#ffa',
'green','red',
'double','ridge',
'1','0.5','0',
'Cooee<br>ROOJA<br>ROOKA',
'Hello<br>MiA<br>LYLU',
'0','70','140'][i], a = [
'color',
'background',
'borderColor',
'borderStyle',
'opacity',
'innerHTML',
'scrollTop'][n];

return function( ){
(n>4?e:e.style)[a] = v}}, b = 
X.getElementsByTagName('*') || null,
i = b.length || 0;
while(i--)b[i].onclick=rE(i);
}(document));
</script></body></html>

Change / Toggle by CSS class.
« «
<!DOCTYPE html><html>
<head><meta charset=utf-8 />
<title>CLASSY</title></head>
<body>
<span id="td0"></span><span id="td1"></span><span id="td2"></span><br />
<span id="Ch"><button class="hC">tC('tc0', 'td0')</button>
<button class="hC">tC('tc1', 'td1')</button> &laquo;<br />
<button class="hC">tC('tc2', 'td0', 'td1', 'td2')</button> &laquo;</span>
<script>
(function(t, q){var L=0, i=0, 
b='background', m='margin', 
S = (function(s){
s.setAttribute('media','screen');
s.appendChild(t.createTextNode(''));
t.head.appendChild(s);
return function(r, h){h = s.sheet;
typeof r !== 'string'?'':
h.insertRule(r, h.cssRules.length)};
})(t.createElement('style'));
S('*{margin:0;padding:0}'); /* << */
S('body{'+b+':tan}'); /* << */
S('#td0,#td1,#td2'.concat('{',
'display:inline-block;',
'width:88px;height:88px;',
'border:1pt dotted #000;',
''+m+':12px 0 0 12px;','}'));
S('.tc0{'+b+':gold}');
S('.tc1{'+b+':red}');
S('.tc2{'+b+':green}');
S('.scD{'+b+':transparent}');
S('.hC'.concat('{',
'font-size:14px;'+b+':#000;',
'color:#ddd;'+m+':9px 0 0 12px;',
'padding:4px 9px','}'));
/* Just for fun the (S)tyle (S)heet 
is done in JS */

/* The utility function below 
will change/toggle classes.
var D is the default class. */
function tC( ){var D='scD',
A = [ ].slice.call(arguments),
d = A.shift( ), I, c = ''; L = A.length;
i = 0; while(i<L){
I = t.getElementById(A[i]) || null;
c = I.className.match(/\S+/g) || '';
c = c.indexOf(d) ? d : '';
I.className = c || D; ++i;}}

 q = t.getElementById(
  'Ch').querySelectorAll('*') || null;
 L = q.length;
/* The above query method (API) 
is in modern browsers. SEE W3.
Line like: getElementsByTagName('*'); */
function rE(n){
return function( ){
n>1?tC('tc2','td0','td1','td2'):
n>0?tC('tc1','td1'):tC('tc0','td0')}}
while(i<L)d[i].onclick = rE(i), ++i;
}(document));
</script></body></html>

Find Love? (Game: CSS class change)
<!DOCTYPE html><html>
<head><meta charset=utf-8 />
<style type="text/css">*{margin:0;padding:0}
body{background:tan}
#gD{display:inline-block;margin:12px 0 12px 12px;white-space:normal}
.fl{float:left;width:108px;height:108px;}
/* H */
.heart{margin:30px 0 0 22px;position:relative;width:50px;height:50px;display:inline-block;
-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);
-ms-transform:rotate(45deg);-o-transform:rotate(45deg);
font-size:22px !important;font-family:sans-serif;
font-weight:700;color:yellow;text-shadow:1px 1px black;
transform:rotate(45deg);background:#c00;
-webkit-transition:background 3s;transition:background 3s}
.heart:before,.heart:after{position:absolute;width:50px;height:50px;
-webkit-border-radius:50%;-moz-border-radius:50%;
-o-border-radius:50%;border-radius:50%;background:#c00}
.heart:before{content:'';bottom:0px;left:-25px}
.heart:after{content:'Love';top:-25px;right:0px}
/* T */
.triangle{width:0;height:0;margin:9px 0 0 9px;display:inline-block;
	border-left:40px solid transparent;
border-right:44px solid transparent;border-bottom:80px solid indigo;
webkit-transition:border-color 3s;transition:border-color 3s}
/* S */
.square{width:70px;height:70px;margin:15px 0 0 12px;background:teal;display:inline-block;
border:4px solid black;webkit-transition:background 3s;transition:background 3s}
/* C */
.circle{width:100px;height:100px;cursor:pointer;display:inline-block;
background:#F62459;border:2px solid teal;-moz-border-radius:50px;
-webkit-border-radius:50px;border-radius:50px;
-webkit-transition:height 2s;transition:height 2s}</style><title>Find Love</title></head>
<body>
<span id="gD">
<span class="fl"><span class="circle" title="?"></span></span>
<span class="fl"><span class="circle" title="?"></span></span>
<span class="fl"><span class="circle" title="?"></span></span></span>
<script>'use strict';
(function(t,G,a){var z=[ ],
C='circle', c='className',
d=t.getElementById('gD'), E=
(d||t).getElementsByTagName('*')||null,
 i=E.length,    /* no(d)e */
r = RegExp('(^|\\s)'+C+'(\\s|$)');
while(i--)r.test(E[i][c])&&
(z[z.length] = E[i]);

F = function(N){var m=0, p=0,
f = function( ){G=1;
z[0][c]=z[1][c]=z[2][c] = C;};
if(G){G=0; i=3;
while(i>1)m = Math.random( )*i--|0,
m!=i&&(p=a[i],a[i]=a[m],a[m]=p);
setTimeout(f, 1e4);} z[N][c]=
a[N]>1?'triangle':a[N]>0?'heart':
'square';}; i=3;  /* ECMA5 bind( ) */
while(i--)z[i].onclick = F.bind(0,i);
}(document, 1, [0,1,2] ));
</script></body></html>

It was Óscar Toledo G auther of http://nanochess.org who inspired me into JS. Here is an entry I once made for the JS 1K Competition. (Full JS SYNTAX version)
<!DOCTYPE html><html>
<head><meta charset=utf-8 /></head>
<body>
<script>;
(function(t,T,f,m,b,w,x,a,I){
var n,c,G,j=0,J=0,z,y=z='#cfc';

function _($,g,v,Q,N,d){
d='getElementById';
/* t.body or id *
N=Q>1?t.body:Q?t[d]('P'):t[d]('D'+$);
g==v?N.onclick=C:
g!=c?N.style[g]=v:
N.innerHTML=v||'&nbsp;'}
_(1,b,'tan',2);t.title=T; /*<<*/

function C( ){var s=
+this.id.substr(1),q=a[s];
if(s&&!I[s])return;
if(!s&&n>7){W(2);return}
I[s]&&(I[s]=0,_(s,c,q),
G&&!(c&1)&&(_( j,c),_( J,c),
I[ j]=I[ J]=1,y=y!=z?z:'#99f'),
c++&1?(G=1,J=s,T==q&&(G=0,
_( j,b,y),_( J,b,y),n++)):(
j=s,T=q),n>7&&_(0,c,c/2))}

a=(x+1+x).split(1);I=a.slice( );
function W(k){var h='82px',
p='#699',r,u,i=16;n=c=G=0;
while(i--)k?(I[i]=1,
k<2&&(I[i]='<button id=D'+i+'>'),
r=Math.random( )*i|0,
r!=i&&(u=a[i],a[i]=a[r],a[r]=u),
k>1&&(_(i,b,p),_(i,c))):(
_(i,w,h),_(i,b,p),
_(i,'height',h),_(i,c),_(i,1,1),
_(i,f,'600 50px sans-serif'));
k==1&&(_(1,0,
'<p id=P>'+T+'<br>'+I.join(''),2),
_(1,w,'330px',1),
_(1,m,'9% auto',1), /* (m)argin9/2 */
_(1,f,'28px sans-serif',1),W( ))}W(1);
}(document,'Memory Game','font',
'margin','background','width',
'{ }1[ ]1( )1||1&1?1:1!'));
</script></body></html>

A complex App. may require Add &/or Remove (ev)ent. Here we go!




<!DOCTYPE html><html>
<head><meta charset=utf-8 />
<style type="text/css">*{margin:0;padding:0}
body{background:tan}
#vX{white-space:normal}
#a0,#a1,#a2,#c0,#c1,#c2,#x0,#x1,#x2{font-weight:600;font-size:13x;width:108px;
font-family:sans-serif;color:#000;height:33px;margin:9px 0 0 4px}
#c0,#c1,#c2,#x0,#x1,#x2{background:#000}
#x0,#x1,#x2{width:35px;margin-left:24px;color:#eee}
</style><title>EVENTS</title></head>
<body>
<span id="vX">
<button id="c0">click</button><button id="c1">mouseover</button><button id="c2">dblclick</button><br />
<button id="a0">click  &laquo;0</button><button id="x0">X</button><br>
<button id="a1">mouseover &laquo;1</button><button id="x1">X</button><br>
<button id="a2">dblclick  &laquo;2</button><button id="x2">X</button><br></span>
<script>;
(function(L,_){var I,
/* ev(object, event, func, 1/0) */
ev=function(i,n,f,b){
var z='attachEvent',
g='addEventListener',
e=['click','mouseover',
'dblclick'][n], o=I[i] || null; 
o[g]?(b?o[g](e,f):
o.removeEventListener(e,f)):
o[z]?(b?o[z]('on'+e,f):
o.detachEvent('on'+e,f)):null},

fy=function( ){alert('Button: ' 
 +this.id.substring(1));},

fx=function( ){var s=this.id,
n=+s.substring(1),
z=function(g,v){
I[g].style.background = v;
I[n+6].style.cursor =
v!='#000'?'default':'pointer'};

if(s[0] == 'a'){
ev(n+6,n,fy,1);z(n+6,'#3c6');
ev(n+3,0,fx,1);z(n+3,'#c00');
ev(n,n,fx,0);z(n,'#000');}

if(s[0] == 'x'){
ev(n+6,n,fy,0);z(n+6,'#000');
ev(n+3,0,fx,0);z(n+3,'#000');
ev(n,0,fx,1);z(n,'');}};

L(function(i){i = 3;
I=_('a0','a1','a2','x0',
'x1','x2','c0','c1','c2');
while(i--)ev(i,0,fx,1);});

/* 2 Utility Functions */
}(function(f,o){o=onload;
onload=typeof o!='function'?f:
function( ){o&&o( );f( )}},

function(e){var i = 0,
L=arguments.length, A = [ ];
for(;i<L;++i){e=arguments[i];
e=typeof e=='string'?
document.getElementById(e):e;
if(L==1)return e;
A[i]=e;}return A}));
</script></body></html>

Canvas - A start (Tutorial).
0-8
^ ^ ^ ^
<>

(: Search rooloose.com online-only :)

<!DOCTYPE html><html lang="en">
<head><meta charset=utf-8 />
<title>Site:Search</title></head>
<style type="text/css">
*{margin:0;padding:0}
body{background:tan}
#sF{display:block;max-height:99px;max-width:350px;background:#CF000F;
margin:9px 0 0 6px;white-space:normal;padding:9px 0 9px 12px;color:gold;border-radius:1em}
#sF,#pl{font:500 17px sans-serif;}#bs,#pl{display:inline-block;}
#pl{width:65%;height:30px;line-height:30px;text-align:bottom;font-size:21px;border:1pt dotted #000;padding-left:4px;background:#ffa;color:#000;overflow:hidden;}
#bs{width:30%;font:600 18px sans-serif;height:30px;
text-align:left;padding-left:3px;cursor:pointer;vertical-align:top}
</style>
<body>
<span id="sF">
(: Search rooloose.com online-only :)<br />
<span id="pl" contenteditable spellcheck="false" tabindex="0"></span>
<input id="bs" type="button" value=": Search" /><br />
<label>(Google <input id="gS" type="radio" name="s" checked />)</label>
<label>(Bing - ms <input id="bS" type="radio" name="s" />)</label>
<label>(duckduckgo <input id="dS" type="radio" name="s" />)</label>
</span>
<script>
(function(t){function _(I){
return t.getElementById(I)}

function S(c){
var URL='rooloose.com',
/* URL = site to search */
y=_('pl').innerHTML,
l=y.length,h='https://';
if(l<2||l>42)return;
y=y.split('&nbsp;').join(' ');
y=y.split(' ').join('%20');
c=t.createElement('a');
c.target='_roo'; c.href=[
h+'www.google.com/#',
h+'www.bing.com/search?',
h+'duckduckgo.com/?'][
_('dS').checked?2:
_('bS').checked?1:0]
+'q='+y+'%20site:'+URL;
c.click( ); c = void 0;} /* +'q='+y; */
_('bs').onclick=S;}(document));
</script></body></html>

Some ODD stuff. (function(n, B){/*Test1 && T2*/ n = +prompt('Test num? Odd : Even',n) || 0; B = n&1 && n%2 ?'Odd':'Even'; alert(n+' is '+B+' Number');}(7)); When you see e it could represent any value such as (e)rror or (e)lement. But combined in a number it is a notation for the number of zeros to tack on or off. alert(1e0 === 1 && 1e1 === 10); alert(1e0+'; '+2e3+'; '+42e5+'; '+3e-5); (function(p, a, b, c, d){ alert( [ /* No rounding up */ (p*a|0)/a, (p*b|0)/b, (p*c|0)/c, (p*d|0)/d].join('\n')); }(Math.PI, 1e8, 1e7, 1e4, 1e3)); (function(D){ /* jan0 - dec11 */ var Y = new Date(D.getFullYear( ), 11, 25), X = D.getMonth()>10&&D.getDate()>25? Y.setFullYear(Y.getFullYear( )+1):+Y, d1 = 864e5; /* 1000*60*60*24 == 1day */ alert(Math.ceil((X-+D)/d1) +' Days to Xmas');}(new Date( ))) Make a (12) numeric string. (function(n, L){ var s = (1e9+'00'+n).slice(-L); alert(s);}(987654321, 12)); (function(n, L){ var s = (1e9+'00'+n).slice(-L); alert(s);}(1, 12)); Random range: For (negative numbers) adjust formula to get the right result. (function(x, n){ /* random intiger */ var ri = (Math.random( )*(x+1-n)|0)+n; alert(ri);}(3, 1)); /* ma(x), mi(n) */ (function(rS, L){/* make random String */ for(;rS.length < L; rS = rS + Math.random( ).toString(36).substr(2)); alert(rS.substr(-L));}('', 8)); /* (L)ength */ ECMA5 DateNow( ); Method. Date.now( ) === +new Date && alert(Date.now( )); /* Milliseconds */ Get a Random Number from +new Date( ); var d = +new Date( )+'', /* 0-99 */ n = +d.slice(-2); alert(typeof n+' '+n);; Note not suitable for multi rapid random No. alert(new Date&1); /* 0-1 */; alert(Date.now()%4); /* 0-3 */; [ ].forEach( parrameter values w3 ) ECMA5 (A)rray LOOP Method. ALSO: Re-visit the default do; while LOOP at the end of Chapter 1. (function(A){ try{ A.forEach(function( v, i ){ alert( v * 5 ); }); }catch(e){e = '[ ].forEach( fail )'; alert(e);} }( [1, 2, 3, 4] )); /* v === A[ i ]; (i)ndex; */ try{ .... }catch(e){ do (e)rror;} ECMA5 Object.keys( ); (function(o, n){ /* n=1 */ var c = '#' + Object.keys(o)[n].substr(1); alert(c);}({xf00:0, x0f0:1, x00f:2}, 1)); (function(o, n){var k, c = '#'; /* n=1 */ for(k in o)if (o[k] == n){ c += k.substr(1); break}; alert(c);}({xf00:0, x0f0:1, x00f:2}, 1)); A House (21) bot. will stay on 17 plus. JS has no (d)elay function to slow the cards to a human (d)elay (999). We only have setTimeout(fn, m); ;'use strict';(function(T, A){ var y = document.getElementById('Y0'), p = function(n){y.style.opacity=(n||1)+''}, f = function(r, i){ /* (Math.random( )*(x+1-n)|0)+n; */ r = (Math.random( )*13|0) + 1; r = r > 9?10:r > 1?r:11;/* Ace = 11 or 1 */ T += A[A.length] = r; i = A.length; if (T>21){while(i--)A[i] > 10 && (A[i] = 1, i = 0, T -= 10)}; i = T>16?1:0; alert(A+(T>21?' T='+T+' BUST': i&&T<21?' T='+T+' pay '+(T+1):' T='+T)); setTimeout(i?p:f, i?777:999)}; y.style.opacity === '1'&&(p(0.4), f( )); }( 0, [ ] )); (function(p, t){p = prompt('TEMP\n' +'Enter: c25 or f77','f77") || 'c0'; t = p[0].toLowerCase( )!=='c'? ((p.substr(1)-32)/9*5).toFixed(2)+' *C': (((p.substr(1)/5*9+32)*100)|0)/100+' *F'; alert(p+' = '+t);}( )); Strip the HTML Tags from ""; (function(H){var s = '', c = document.createElement('div'); c.innerHTML = H; /* Browser */ s = c.textContent || c.innerText || ''; c = void 0; alert('|'+s+'|'); }('<p><s>noHTML</s></p>'));

Did you know JS is now the most used Programing Language in the world. It is also true that once you learn one language the move to other languages like C, C++; etc... is easy!

Some people are Number people some people are word (String) people. I will not lie to you. JS will work best for you if you work with typeof Number; wherever you can. Even when input / output is String.

The ECMA Method Number.isFinite(v); is well supported. It returns false if v is + or - infinity or NaN. (function( ){function N(v){ return (!+v!==+v && isFinite(v))}alert( N(7)+', '+N('007')+', '+N(NaN));}( )); It can be difficult to verify that a given value is a numerical string or number. var v = '042'; if (v-v === 0 && v !== +v) alert(''+v+' is numeric '+typeof v); var v=5; if (v === +v)alert('v is '+typeof v); var v = 5.00; /* JS Intiger Number (5) */ if (typeof v=='number' && v == (v|0)) alert(v); In JS a Number trailing 0 is removed. 5.0 or 5.00 becomes the intiger 5 5.50 becomes 5.5 var v = 5.50; /* Float Number */ if (typeof v=='number' && v != (v|0)) alert(v); Sorting and removing duplicate Strings for output can be a simple pattern job. (function(a, b){var s='', o={ }, oA=[ ], i = -1; for(;s=a[++i];)s && typeof s=='string' && (o[a[i]] = 1); i = -1; for(;s=b[++i];)s && typeof s=='string' && (o[b[i]] = 1); /* any more ? */ i = 0; for(oA[i++] in o); alert('oA = ['+oA+']'); }( ['a', 'b', 'c', 'd'], ['x', 'y', 'b', 'z'] )); We should also have a discussion on what parts of JS we should maybe avoid. With time and 'Stress Testing' JS flaws become apparent. Words / Statements that are not forbidden but to avoid or be carefull with are:- eval( ); setTimeout( ); setInterval( ); new Something. prototype, this, with( ); clear( ); break; and more. Always Question everything: Always ask 'How', 'Why'? Is there a better way? Is there a faster way? This BOOK stays out of the Global Scope as JS Pros. Need to own it! Browser Scope is like a Russian Doll. The big Doll is the tab / window['Global Scope']. Please do NOT create a Global var unless you intend to! All Book 'code blocks' are tested in ECMA5 'use strict'; mode. The source Code (View Source) of this Book probably breaks most rules. This is so the Source file reads "in order" and for ease of maintenance. If you scroll to the bottom of the Source file you will see a small script; roo_eBook.js This sets your background as self.name = "DAY / NiGHT color"; Storage (local) only saves your NOTES. Storage has been removed from HTML5 as it is | Not Secure | but just fine for your everyday notes!

A special thanks to the links included in this book and for any examples lifted.

This book does not harvest any data. Sets no cookies and has no form tags. No Ajax, no XML, no analytics. All roo APPs are offered in good faith. THANKS FOR READiNG If you are (of age) 18++; and wish to donate for the hosting and upkeep of this BOOK. Please use this Card / PayPal link to online FORM. PayPal: A way to pay online! ^ ^ ^ ^