// 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
/***********************************************************************/