ECMAScript



    ECMAScript Standard
    Global Object
     
    	/*
    	In client-side JavaScript, the Window object serves as the global object for all JavaScript code 
    	contained in the browser window it represents. 
    	This global Window object has a self-referential window property that can be used instead of this 
    	to refer to the global object. The Window object defines the core global properties, 
    	but it also defines quite a few other globals that are specific to web browsers 
    	and client-side JavaScript. 
    	
    	*/
    	
      var global = window = this; // Define a global variable to refer to the global object 
    
      log( global );
    
    Wrapper Objects
     
      /*
      JavaScript objects are composite values: they are a collection of properties or named values. 
      We refer to the value of a property using the . notation. 
      When the value of a property is a function, we call it a method. 
      To invoke the method m of an object o, we write o.m().
    
    
    	Strings are not objects, though, so why do they have properties? 
    	Whenever you try to refer to a property of a string x, 
    	JavaScript converts the string value to an object as if by calling new String(x).  
      */
     
     	var x = "hello world!"; // A string
     	var y = x.substring(x.indexOf(" ") +1 , x.length) ; // Use string properties
    
    	 
     /*
     Note that it is possible (but almost never necessary or useful) 
     to explicitly create wrap- per objects, by invoking the String(), Number(), or Boolean() constructors: 
     */	 
      
      var s = "test", n = 1, b = true; 		// A string, number, and boolean value.
      var S = new String(s); 				// A String object 
      var N = new Number(n); 				// A Number object
      var B = new Boolean(b); 				// A Boolean object
     
     
     log( );	
    	 
    
    Type Conversions
     
    /*
    	 JavaScript is very flexible about the types of values it requires. 
    	 We have seen this for booleans: when JavaScript expects a boolean value, 
    	 you may supply a value of any type, and JavaScript will convert it as needed. 
    	 Some values convert to true and others convert to false. 
    	 The same is true for other types: if JavaScript wants a string, 
    	 it will convert whatever value you give it to a string. 
    	 If JavaScript wants a number, it will try to convert the value you give it to a number 
    	 (or to NaN if it cannot perform a meaningful conversion). Some examples:
     
     */
    
    	 10 + " objects" // => "10 objects". Number 10 converts to a string
    	 
    	 "7" * "4" 	// => 28: both strings convert to numbers
    	 
    	 var n = 1 - "x"; // => NaN: string "x" can't convert to a number
    	 
    	 n + " objects" // => "NaN objects": NaN converts to string "NaN"
     
     log();
    
    
    Conversions and Equality
     
    /*
    	Because JavaScript can convert values flexibly, 
    	its == equality operator is also flexible with its notion of equality. 
    	All of the following comparisons are true, for example: 
    */
    
    	null == undefined // These two values are treated as equal.
    	
    	"0" == 0         // String converts to a number before comparing.
    	
    	0 == false      // Boolean converts to number before comparing.
    	
    	"0" == false  // Both operands convert to numbers before comparing.
    	
    
    log( ) ;
    	
    
    Explicit Conversions
     
    /*
    	JavaScript performs many type conversions automatically, 
    	you may sometimes need to perform an explicit conversion, 
    	or you may prefer to make the conversions explicit to keep your code clearer.
     
    */ 
    
    	1.23 			// A number literal
    	"hello" 		// A string literal
    	/pattern/ 		// A regular expression literal
    
    
    	Number("3")			// => 3 
    	
    	String(false) 		// => "false" Or use false.toString()
    	
    	Boolean([]) 		// => true
    	
    	Object(3)			// => new Number(3)
    	
    	[1,2,3].toString() 	// => "1,2,3"
    	
    	(function(x) { f(x); }).toString() // => "function(x) {\n f(x);\n}"
    	
    	/\d+/g.toString() 	// => "/\\d+/g"
    	
    	new Date(2010,0,1).toString() // => "Fri Jan 01 2010 00:00:00 GMT-0800 (PST)"
    	
    	var d = new Date(2010, 0, 1); // January 1st, 2010, (Pacific time)
    	
    	d.valueOf() // => 1262332800000
    	
    	var now = new Date(); 	// Create a Date object
    	typeof (now + 1) 		// => "string": + converts dates to strings
    	typeof (now - 1)		// => "number": - uses object-to-number conversion
    	
    	
    	now == now.toString() // => true: implicit and explicit string conversions
    	
    	now > (now -1) // => true: > converts a Date to a number
    	
    	
    	
    	
    log();
    
    
    The Conditional Operator (?:)
     
    /*
    		 x > 0 ? x : -x 		// The absolute value of x
    
    */ 
    	username = 'Jalal Hejazi'
    	
    	greeting = "hello " + (username ? username : "there");
    	
    	
    	// This is equivalent to, but more compact than, the following if statement:
    		
    	greeting = "hello "; if (username)
    	greeting += username; else
    	greeting += "there";
    
    
    log( greeting );
    
    The typeof Operator
     
    /*
    	typeof is a unary operator that is placed before its single operand, which can be of any type. 
    	Its value is a string that specifies the type of the operand. 
    	The following table specifies the value of the typeof operator for any JavaScript value: 
    
    	  (typeof value == "string") ? "'" + value + "'" : value 
    	
    */ 
    
    
    	// undefined 
    	// Nan
    	// null
    	// "string"
    	// 123
    	// window
    	// this
    
    	var value = this 
    	
    	log(  
    	      (typeof value == "string") ? "'" + value + "'" : value
    	    
    	    );
    
    
    The delete Operator
     
    /*
    	delete is a unary operator that attempts to delete the object property or array element specified as its 
    	operand.1 Like the assignment, increment, and decrement operators, 
    	delete is typically used for its property deletion side effect, 
    	and not for the value it returns. Some examples: 
    */ 
    
    	var o = { x: 1, y: 2};  // Start with an object
    	
    	delete o.x;				// Delete one of its properties
    
    	log( o.x == undefined , "The property x is deleted !" )
    	log( o.y == 2 		, "The property y is still available " )
    
    
    
    Exception Handlers
     
    
    	//The following code illustrates the syntax and purpose of the try/catch/finally statement:
    	
    	try {
    		// Normally, this code runs from the top of the block to the bottom 
    		// without problems. But it can sometimes throw an exception,
    		// either directly, with a throw statement, or indirectly, by calling 
    		// a method that throws an exception.
    	}
    	catch (e) {
    		// The statements in this block are executed if, and only if, the try
    		// block throws an exception. These statements can use the local variable 
    		// e to refer to the Error object or other value that was thrown.
    		// This block may handle the exception somehow, may ignore the
    		// exception by doing nothing, or may rethrow the exception with throw.
    	}
    	finally {
    		// This block contains statements that are always executed
    		 
    	}
    	
    	
    	try {
    			
    			// Ask the user to enter a number
    			var n = Number(prompt("Please enter a positive integer", ""));
    			
    			// Compute the factorial of the number, assuming the input is valid 
    			var f = factorial(n);
    			
    			// Display the result
    			alert(n + "! = " + f);
    		
    		}
    		catch (ex) 
    		{ 
    			// If the user's input was not valid, we end up here
    			// Tell the user what the error is 
    			log(ex);
    		}
    
    
    Object Literals
     
    /*
    	The easiest way to create an object is to include an object literal in your JavaScript code. 
    	An object literal is a comma-separated list of colon-separated name:value pairs, en- closed within curly braces. 
    	A property name is a JavaScript identifier or a string literal (the empty string is allowed). 
    	A property value is any JavaScript expression; the value of the expression (it may be a primitive value or an object value) 
    	becomes the value of the property. Here are some examples: 
    */ 
    
    	var empty = {};		// An object with no properties
    
    	var point = { x:0, y:0 };	// Two properties
    	
    	var point2 = { x:point.x, y:point.y+1 };  // more complex object
    	
    	var book = {
    				"main title": "JavaScript", 
    				'sub-title': "The Definitive Guide", 
    				"for": "all audiences",
    					author: {
    							firstname: "David", 
    							surname: "Flanagan"
    							} 
    				};
    
    	
    	// Create Object using new:
    	var o = new Object();
    	var a = new Array();
    	var d = new Date();
    	var r = new RegExp("js");
    
    	/*
    	Every JavaScript object has a second JavaScript object (or null, but this is rare) associated with it. 
    	This second object is known as a prototype, and the first object inherits properties from the prototype. 
    	*/
    
    	var o3 = Object.create(Object.prototype); // o3 is like {} or new Object().
    	
    	var o = {
    				// An ordinary data property 
    				data_prop: value,
    				
    				// An accessor property defined as a pair of functions 
    				get accessor_prop() { /* function body here */ },
    				
    				set accessor_prop(value) { /* function body here */ }
    			};
    		
    		
    		
    		var p = {
    					// x and y are regular read-write data properties. 
    					x: 1.0,
    					y: 1.0,
    					
    					// r is a read-write accessor property with getter and setter.
    					// Don't forget to put a comma after accessor methods.
    					
    					get r() { return Math.sqrt(this.x*this.x + this.y*this.y); }, 
    					set r(newvalue) {
    										var oldvalue = Math.sqrt(this.x*this.x + this.y*this.y); 
    										var ratio = newvalue/oldvalue;
    										this.x *= ratio;
    										this.y *= ratio;
    									},
    					// theta is a read-only accessor property with getter only.
    					get theta() 
    					{ 
    						return Math.atan2(this.y, this.x); 
    					} 
    				};		
    	
    	
    	/*
    		If you want to create or modify more than one property at a time, 
    		use Object.define Properties(). 
    		The first argument is the object that is to be modified. 
    		The second argument is an object that maps the names of the properties to be 
    		created or modified to the property descriptors for those properties. 
    		For example: 
    	*/
    	
    	var p = Object.defineProperties({}, 
    			{
    					x: { value: 1, writable: true, enumerable:true, configurable:true }, 
    					y: { value: 1, writable: true, enumerable:true, configurable:true }, 
    					r: {
    							get: function() { return Math.sqrt(this.x*this.x + this.y*this.y) }, 
    							enumerable:true,
    							configurable:true
    						} 
    			});
    	
    	
    	
    		/*
    			Object serialization is the process of converting an objects 
    			state to a string from which it can later be restored. 
    		*/
    
    			o = {x:1, y:{z:[false,null,""]}}; // Define a test object	
    			
    			s = JSON.stringify(o); // s is '{"x":1,"y":{"z":[false,null,""]}}'
    			
    			p = JSON.parse(s); // p is a deep copy of o
    			
    			var s = { x:1, y:1 }.toString();
    			
    			
    			
    			
    
    			
    	
    
    Inheriting Object Properties
     
    /*
    	Inheriting Object Properties
    */ 
    
    	function Rectangle(w,h) {
    		this.width = w;
    		this.height = h;
    	}
    	
    	Rectangle.prototype.area = function() {
    		return (this.width * this.height);
    	}
    	Rectangle.prototype.toString = function() {
    		return "Rectangle of width: " + this.width + " and height: " + this.height;
    	}
    	Rectangle.prototype.valueOf = function() {
    		return this.area();
    	}
    	Rectangle.prototype.equals = function(oRect) {
    		return (this.width == oRect.width && this.height == oRect.height);
    	}
    	Rectangle.prototype.compareTo = function(oRect) {
    		return (this.area() - oRect.area());
    	}
    	
    	function DepthRectangle(w,h,d) {
    		Rectangle.call(this,w,h);
    		this.depth = d;
    	}
    	DepthRectangle.prototype = new Rectangle();
    	DepthRectangle.prototype.constructor = DepthRectangle;
    	
    	DepthRectangle.prototype.volume = function() {
    		return (this.area() * this.depth);
    	}
    	DepthRectangle.prototype.toString = function() {
    		return "DepthRectangle with width: " + this.width + 
    				" & height: " + this.height + 
    				" & depth: " + this.depth;
    	}
    
     
     
       // Test the implementation 
        
         var myRect = new Rectangle(5,6);
    	var myDeepRect = new DepthRectangle(7,8,9);
    	
    	log("myDeepRect.volume() = ",              myDeepRect.volume());
    	log("myDeepRect.area() = "  ,              myDeepRect.area()  );
    	log("myRect instanceof DepthRectangle " ,  myRect instanceof DepthRectangle);
    
    	var myRect2 = new Rectangle(7,8);
    	var myRect3 = new Rectangle(5,6);
    	var myRect4 = myRect;
    	
    	log("typeof myRect : " ,  				 typeof myRect);
    	log("myRect instanceof Rectangle : ", 	 myRect instanceof Rectangle);
    	log("myRect instanceof Object :" , 		myRect instanceof Object);
    	log("myRect.toString() " , 				myRect.toString());
    	
    	log("myRect.equals(myRect2) " ,         myRect.equals(myRect2));
    	log("myRect.equals(myRect3) " ,         myRect.equals(myRect3));
    	log("myRect.equals(myRect4) " ,         myRect.equals(myRect4));