// JavaScript tutorial by Sandeep Desai http://www.thedesai.net // JavaScript is a interpretive langauge which mixe Java and Perl // ; optional if one statement per line // All numbers are 64 bit floating point numbers IEEE 754 standard // All numbers can be represented as integers 2^-53 to 2^53 // Numbers can represented as Hex using 0xff or 0XFF // Floating point numbers 3.14, 123.45e11 //Number constants Infinity, NaN, Nubmer.MAX_VALUE, Number.MIN_VALUE, Number.NaN, // Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY // Strings are immutable // == operator for string does an equals // Lisp like lambda functions var square = function(n) { return n*n; } var a = 12; var b = a.toString(16); //Hex var s = "Hello's"; s = "This is
\" \' \\ \x30 \u0030 string"; s = s + " Hello"; var b = s.length; // string length b = s.charAt(2); s = s.substring(2, 4); b = s.indexOf('H'); // find index where H character is b = 3; b = "ACME"; // can assign different data type to same variable // creating objects var p = new Object(); p.name = "Foo"; p.phone = 123; p = {name:"Bar", phone:345}; p["name"] = "bar2"; var business = new Object(); // can nest assignments see page 40 business = { company: "ACME", employee: { name: "Bugs", phone: 987 }}; var s = business.employee.name; var ar = new Array(); ar[0] = 123; ar[1] = "blah"; ar[2] = {name:"Bar", phone:345}; var br = new Array(4); // create with 4 elements // Array literals; br = [123, 4.5, "brr!", {month:"Jun", day:9, year:88}]; cr = [br[0], br[2]]; dr = cr; // both dr and cr point to same array as they are references sparsearray = [1,,,4]; if (sparsearray[1] == null) document.write("is null
"); // JavaScript has undefined ??? var d = new Date(2005, 6, 4); document.write(d.getDay()); // Runtime Error objects, each object has message property // Error, EavalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError // Wrappers are defined for primitive object types, // string and String object can be used interchangeably // eval() takes a string and not String var s = new String("Blah"); // String wrapper Object // variable types are untyped, // Number, boolean and null and undefined are primitive // Objects, array and functions are references // can be redeclared // if not initialized set to UNDEFINED // Good practice to always declare variables with var // no block variable scope like Java // in function variables defined in a block are set to undefined from start of block till // variable declaration // usage of undeclared variable will cause error // usage of declared unassinged variable will not cause error // Strings are immutable // Java implicitly creates a global variable to hold all variables as properties // local variables are properties of call object var i = 0, h = "hello"; var i = 2; // can redeclare variables var k; // k is UNDEFINED //i = kkk +1; // undeclared variable usage will cause error // declared unassinged variable will not cause error document.write(i +"
"); // var variables are permanent and cannot be deleted var q=1; this.q=1; for (var i=1; i<5; ++i) q=q*i; /********************************* operators *************************/ // will convert data type // Numeric + - * / % - ++ -- += -= etc // / returns floating point // = for assignment // comparison == === != !=== > < <= >= (can compare any type of data) // == same primitive or same reference null == UNDEFINED is true // 3 == "3" is true, "1" == true is true // if object == primitive try with object.toString() and object.valueOf // === identity operator, same type, same object, same string data // for > < etc if string compare to number then convert string to number // object converted to numeric first and then compared // + converts arguments to numeric // use String.localeCompare() instead of == for locale specific compare // use in operator to check if object or array has a property // logical operator && || ! // shortcircuit evaluation of && if (a && b) if a is false b not evaluated // bitwise operators & | ^ (XOR) ~ (NOT) << >> >>> <<< // ? : ternary operator // instanceof // typeof evaulates to number, string, boolean, function, object (for object, array and null) // delete can delete property // can access property by doing using . or [] operator with [] you can pass variable that has property name q = "1" + 0; // number 0 converted to string result is "10" var r = "3" < 4; // converts string to number document.write("is string '3' < 4 " + r + "
"); r = "abc" < 4; // evaluated as NaN < 4 document.write("is string 'abc' < 4 " + r + "
"); var person = {name:"Bar", phone:345}; var b = "name" in person; // in operator true var d = new Date(); b = d instanceof Date; // true b = d instanceof Object; //true d instanceof Number; // false b = typeof(d) == "object"; //true s = 1 + 2 + "abc"; // is "3abc" s = "abc" + 2 + 1; // is "abc21" b = "3" < 10; // is true as 3 convert to number var person = {name:"Bar", phone:345}; person.name; person[name]; delete person.phone; // delete property delete person;// returns false cannot delete declared variable f = 1; delete f; // delete successfull typeof person.name; // is undefined /********************** controls and statements *******************/ // if else // switch (n) { case 1: ... break; ...; default: break; } // case can be arbitary expression, recommend that constants be used // while (expression) statement; // do statement; while (expression) // for (initialzie; test; increment) statement; // for (variabele in object) statement; // for in loop properties in a object // labels, assign labels to statement foo: // break to break of out of loop can do break foo; where foo is label // continue -> continue to next iteration of loop // try {} catch(ex) {} finally {} // with (object) statement e.g with(person) name = "foo"; makes code hard to read and slow if (checkValue(b)) document.write(s); a1 = "hello"; b1 = "he"; switch (a1) { case b1+"llo": document.write("matched case in switch
"); break; } document.write("for in object
"); var person = {name:"Bar", phone:345}; for (var prop in person) { document.write(prop + "=" + person[prop] + "
"); } document.write("for in array
"); var ar = [1, 2, 3]; for (var prop in ar) { document.write(prop +","); } document.write("
"); // Exception handling // try {} catch(ex) {} finally {} try { n = nonvar; } catch (ex) { document.write("Caught exception " + ex + "
"); } /******************** functions *********************/ // function name(arg0,arg1,...,argn) { statements; } // return for returning result // primitive number and boolean passed by value everyting else passed by reference // functions can be stored in objects, arrays can be passed as argument // Function() constructor create functions at run time, avoid using in loops as they will be slow // also known as anonymous functions // functions can be passed as parameters useful in Array.sort // functions have special arguments object, can be used to implement functions with variable length arguments // arguments object has callee property which refers to function being executed // useful for recursively executing unnamed functions e.g arguments.called(x-1); // arguments.callee.length equals number of arguments defined for function // arguments.length is acutal number of arguments passed in an invocation // can define function.properties which are static variables // apply() and call() methods, call() implemented in JavaScript 1.5 // apply and call used for objects e.g call(o, 1, 2) or apply(o, [1,2]); // apply takes array the first parameter is this // functions can be created at run time are called closure var t1 = 5; function checkValue(n) { // t1 is undefined here as local t1 used not global var t1 = 3; //local scope variable t2 = 4; // global scope function nested() {} // can have nested functions if (n == 3) { var t3 = 5; // scope is function and not block return true; } else return false; } // Function() constructor dynamically create functions // takes any number of string arguments // also known as anonymous functions // var f = new Function("x", "y", "return x*y;"); document.write(" Function constructor -> " + f(2,3) + "
"); // Functions as data, pass function as parameters function sq(x, y) { return x*y; } function function_as_data(func, p1, p2) { return func(p1, p2); } document.write("function as data ->" + function_as_data(sq,2,3) + "
"); // arguments array function sq(x, y) { if (arguments.length != 2) return 0; else { arguments[0]++; // will increment x also return x*y; } } // variable number of arguments function max() { var m = 0; for (var i =0;i< arguments.length; ++i) if (arguments[i] > m) m = arguments[i]; return m; } max(3, 9, 4, 8); // funciton properties, use for static variables in function sequence.counter = 0; function sequence() { return sequence.counter++; } // closure var y = "global"; function constructFunction() { var y = "local"; return new Function("return y"); } constructFunction()(); // returns global /*********************** objects *************************/ // no concept of class, inheritance using prototyp property // use for in to enumerate properties // can create new properties by doing foo.prop = new Object() // delete prop; // define method as propertie and set them to functions // prototype based inheritance not class based // all objects have a prototype property // when property read via prototype if not found fetch parent object property // for write we do it in the current object only // every object has its own instance properties // Class methods are properties (data) // Class methods are really global functions // Use function literal sybtax for defining methods // Object.prototype.method = function() { .. } // prototype is property is just an object // objects have constructor property refers to constructor function used to create object // object should implement a meanigful toString method // can also implemente toLocaleString() (implemented by Date, Math, Array, Number) // valueOf method should return primitive type // hasOwnProperty, propertyIsEnumerable, isPrototypeOf var person = { name: "foo", phone: 123 }; person.company = new Object(); person.company.name = "ACME"; var prop = "name"; document.write("Object person.name = " + person.name + "
"); document.write("Object person[prop] = " + person[prop] + "
"); delete person.company; // delete company property function Person_is_teen() { if (this.age > 12 && this.age < 20) return true; else return false; } // Constructor function Person(name, age) { this.name = name; this.age = age; // inefficient as each object has property this.is_teen1 = Person_is_teen; // define method properties } // better approach supports inheritance Person.prototype.is_teen = Person_is_teen; // use this approach to define class methods Person.prototype.is_toddler = function() { if (this.age > 2 && this.age < 5) return true; else return false; } // Implement toString useful for + or document.write or wherever String required Person.prototype.toString = function() { return this.name + "," + this.age; } Person.prototype.valueOf = function() { return this.age; } function Employee(name, age, manager) { this.name = name; this.age = age; this.manager = manager; } Employee.prototype = new Person("", 0); // setup inheritence Employee.prototype.getManager = function() { return this.manager; } var e = new Employee("foo", 25, "bar"); Person.prototype.MIN_AGE=0; // use prototype for defining constants // can extend objects like String String.prototype.print = function() { document.write(this + "
"); } var p = new Person("foo", 15); document.write("Invoking method is_teen " + p.is_teen1()); document.write(" Invoking method is_teen " + p.is_teen() + "
"); document.write(" Person p= " + p + "
"); p.constructor == Person; // is true, object may not have valid constructor property //useful typeof function returns class name function Typeof(x) { var t = typeof x; if (t != "object") return t; var c = Object.prototyp.toString.apply(x); c = c.substring(8, c.length-1); // strip out initial object part return c; } // hasOwnProperty Javascript function returns true if non inherited property e.hasOwnProperty("getAge"); // false defined by parent object e.hasOwnProperty("getManager"); // true // propertyiSEnumerable returns false for function property // isPrototypeOf return true if object is prototype object of argument /***************** Associative Array ****************************/ // Hashtables var emp = "foo1"; var mgr = "bar1" var hr = new Object(); hr[emp] = mgr; hr["foo2"]= mgr; hr[mgr] = "ceo"; for (var prop in hr) { document.write(" hr[" + prop + "]=" + hr[prop]); } /*************************** Array *********************/ // Arrays can be sparse // can have any data types // length is last positive index + 1 // length is a read write property // length may not be size of array // trunc array by setting length property // array.join() convert to String // array.reverse, sort, concat, // slice subarray // splice insert remove elements, modifies array // push() pop() for stack // shitf() unshift() insert remove from start of array var ar = new Array(); var ar = new Array(10); // create with 10 elements ar = new Array(1, 2, 3, "abc"); ar = [1, 2, 3, "abc", true, [11, 22, {n:"foo", age:2}]]; v = ar[0]; ar[1] = 22; ar[-3] = 33; // Creates a string property of "-3" ar["foo"] = "bar"; var s = ar.join(); // convert to string s = ar.join("@"); // convert to string using @ instead of , var ar2 = new Array(); ar2[0] = 1; // length = 1; ar2[1] = 2; // length = 2; ar2[99] = 3; // length = 100; ar2[-1] = 3; // length still 2 ar2[3] == undefined; // is true ar2.length = 2; // truncate array will still have ar[-1] ar = [1,9,3]; ar.sort(); // alphabetical sort ar.sort(function(a,b) { return a-b; }); // numerical sort ar.concat(17, 12); // concat elements ar.concat(7, [2, [3,4]]); // concat elements ar = [1,2,3,4,5]; ar.slice(1, 3); // 2,3,4 subarray ar.slice(3); // 5,6 ar = [1,2,3,4,5]; ar.splice(3); // ar=[1,2,3] returns 5 ar = [1,2,3,4,5]; ar.splice(1, 2); // return 2,3 a is 1,4,5 ar = [1,2,3,4,5]; ar.splice(1,2,'a','b'); // return 2,3 a is 1,'a', 'b',4,5 ar.splice(1,2,[7,8,9]); // var stack=[]; stack.push(1,2,3); stack.pop(); // remove 1 stack.push([4,5]); stack.pop(); // [4,5] var q = []; q.unshift(1); q.unshift(2); // [2,1] q.shift(); // 1 document.write(q.toString()+"
"); /************************ Regular Expressions ************************/ // JavaScript 1.2 roughly implements Perl4 regular expressions // JavaScript 1.5 roughly implements Perl5 regular expressions // JavaScript 1.5 implements non greedy repition that is match the fewest // RegExp methods: exec test // RegExp properties: source global ignoreCase multiline lasIndex // String methods: search replace match (like String.split() in Java) // literal characters \0 \t \n \r \xnn (\x0A is same as \n) \uxxxx \cX // ^ $ . * + ? = ! : | \ / ( ) [ ] { } // [...] match character between the brackets // [^...] match any one character not in brackets // . Any character except new line // \w same as [a-zA-Z0-9_] // \W same as [^a-zA-Z0-9_] // \s Any unicode whitespace character // \S not unicode whitespace // \d same as [0-9] // \D same as [^0-9] // {n,m} match previous item at least n times but no more than m times // {n,} match previous item at least n times // {n} match previous item n times // ? match zero or one sames as {0,1} // + match one or more same as {1,} // * match zero or more same as {0,} // grouping // | or // (...) grouping can be use with * + ? ! // (?:...) group only // \n match the same character that were matched when group number n was reached // specifying match position // ^ match at begining // $ match at end // \b match a word boundary // \B match a position that is not a word boundary // (?=p) a positive look ahead assertion // (?!p) a negative look ahead assertion // flags // i case insensitive /java/i match jAvA // g perform a global match // m multiline mode // perl regular expression not supported // s (single-line mode) an x (extended syntax) flags // \a \e \l \u \L \U \E \Q \A \Z \z \G escape sequences // (?<= and (?"); s = "1 + 2 = 3"; var a = s.match(/\d+/g) // return array ["1","2","3"] document.write(a); /*************************** Data Conversion *******************/ var x = "13"; var x_to_string = x + ""; var x_to_number = x - 0; var n = 20; n.toString(2); // binary conversion n.toString(); var x = Number(x); // explicit to number string should be base 10 no whitespaces parseInt("12 apples"); // returns 12 parseInt("0xFF"); // 255 parseInt("11", 2); // second parameter radix returns 3 parseFloat("2.5 inches"); // returns 2.5 n = 123.456; // JavaScript 1.5 n.toFixed(0); // 123 n.toFixed(2); // 123.45 // toExponential toPrecision /***********************************************************************/