Monday, March 27, 2017

JavaScript I



JavaScript


 How is JavaScript related to Java?
A common misconception is that JavaScript is closely related to Java. It is true that both languages have a C-like syntax but that is where the similarity ends. With Java you can create standalone applications, but this is not how JavaScript works. JavaScript requires a hosting environment which most commonly is the browser. The JavaScript code is embedded in HTML documents and its primary use is to add interactivity to HTML pages. Many developers don't realize this, but JavaScript itself does not have the facilities to provide input and output to the user, it relies on the DOM and the browser for that.
Another difference is that Java is statically typed whereas JavaScript is a dynamically typed language. In a statically typed language (e.g. Java, C#, C++) you declare variables that are of a certain type, such as, integer, double, or string. At runtime these types do not change. Assigning a string to an integer variable will result in an error.

// Java
int total = 131;
total
= "This is Java";      // Error. In fact, won't even compile
In JavaScript, which is a dynamically typed language, a variable can hold any type of value, such as integer, string, Boolean, etc. Moreover, at runtime, the type can be changed. For instance, a variable that is bound to a number can easily be re-assigned to a string.
Here is an example where the same variable is assigned to a number value, a string, an object, and even a function; and it all works fine:

// JavaScript
var total = 131;                         // number
total
= "This is JavaScript";            // string
total
= {"Customer": "Karen McGrath"};   // object
total
= function () {alert("Hello");};   // function
total
();                                 // => Hello (executes function)
Both Java and JavaScript borrow their programming syntax from C. For example, for, do while, while loops, and if, switch, break, and continue statements all exist in JavaScript. Here are some examples:

for loop

var count = 0;
for (var i = 0; i < 10; i++) {
    count
+= i;
}
alert
("count = " + count);         // => count = 45

while loop

var i = 0;
count
= 100;
while (i < count){
   i
++;
}
alert
("i = " + i);                 // => i = 100

switch statement

// switch statement
var day = new Date().getDay();
switch(day) {
  
case 0:
      alert
("Today is Sunday.");
     
break;
  
case 1:
      alert
("Today is Monday.");
     
break;
  
case 2:
      alert
("Today is Tuesday.");
     
break;
  
case 3:
      alert
("Today is Wednesday.");
     
break;
  
case 4:
      alert
("Today is Thursday.");
     
break;
  
case 5:
      alert
("Today is Friday.");
     
break;
  
case 6:
      alert
("Today is Saturday.");
     
break;
  
default:
      alert
("Today is a strange day.");
}

if-then-else

var value = 9;

if (value < 0) {
   alert
("Negative value.");
} else if (value < 10) {
   alert
("Between 0 and 9, inclusive.");
} else {
   alert
("Greater than or equal to 10.");
}

break and continue

for (var i = 0; i < 100; i++) {
  
if (i < 5) {
     
continue;
  
} else if (i > 7) {
     
break;
  
}
   alert
(i);         // => 5, 6, 7
}

try, catch

try {
    doesNotExist
();
}
catch (ex) {
    alert
("Error: " + ex.message);    // => Error details
}

Scoping
Most languages support block-level scoping. Block level variables only exist within the context of a block of code, such as an if or a for statement. In the Java example below, the variable count only exists inside the curly braces. It is not visible or accessible outside the block.

// Java
if (accept == true) {
  
int count = 0;                     // block level scope
  
... 
}

Function level scope
In JavaScript there is no block level scoping, but it does support function-level scoping. Function level variables that are declared inside a function are only available and visible to that function.

// JavaScript
function calculate () {
  
var count = 0;                     // function level scope
  
...                  
}


Terminating semicolons
Statements in JavaScript are delimited with semicolons. You can omit semicolons because the JavaScript engine has an auto-insertion mechanism which adds semicolons where it thinks they are missing. The problem is that this may cause unintended side effects.
For this reason, you should always terminate your statements with semi-colons explicitly. Below is an example of how JavaScript looks at statements differently from what the developer intended.
Consider these 2 statements without semi-colons:

// anti-pattern!
sum
= total1 + total2
(total3 + total4).x()
JavaScript will interpret this as:

sum = total1 + total2(total3 + total4).x();

Here is another example of what can go wrong:

// anti-pattern!
function sumSquared(x,y) {
   
return
       
(x * x) + (y * y);
}

alert
(sumSquared(3,4));         // => undefined


This function will always return undefined because it executes the code with a semicolor following return:

function sumsquared(x,y) {
   
return;                     // semicolon added!
       
(x * x) + (y * y);
}

JavaScript is weakly typed
As mentioned before, JavaScript is a weakly-typed language. A variable can be bound to any data type and then change its type. For instance, a variable with a value of 1 can be changed to "Hello", followed by an object assignment.
Sometimes this has confusing consequences. For example, when JavaScript encounters the expression "2" + 1, it implicitly converts the numeric 1 to a string and returns the string "21". Even the expression null + 0 is legal in JavaScript and returns 0. Such implicit conversions can cause program errors that are difficult to detect.

alert(null + 34);               // => 34

Functional programming
JavaScript supports a functional programmingstyle. Functions in JavaScript are first-class citizens which it derives from the Scheme programming language. In fact, functions are objects and therefore a function can also have properties and methods.
There is more you can do with functions; you can store them in variables, passed them around as function arguments, and return them as the return value of a function. In JavaScript the difference between code and data can be blurry at times, a characteristic it borrows from the Lispprogramming language. Here is an example of a function assigned to a variable. The function is executed by appending the variable name with two parentheses.

var say = function() {
    alert
("Hello");
};

say
();                          // => Hello
Next is an example of a function that is passed as an argument to another function:

var say = function() {
    alert
("Hello");
};

function execute(callback) {
    callback
();
}

execute
(say);                  // => Hello
And here is an example of a function that is returned by another function:

function go() {
   
return function() {
        alert
("I was returned");
   
};
}

var result = go();
result
();                    // => I was returned
JavaScript supports functions nested within other functions. The nested functions are called methods. Methods have access to all parameters and local variables of the functions it is nested within. Below is an example where the nested say function has access to the name variable in the outer function:

function person(first, last) {

   
var name = first + " " + last;

   
function say() {       // method, nested function
        alert
(name);
   
}

    say
();         
};

person
("Joe", " McArthur ");     // => Joe McArthur
Arrays are also objects and the built-in array methods such as map, filter, and reduce possess the characteristics of a functional programming style; so they also have access to all array values. Arrays are discussed later.


JavaScript is object-oriented, but class-less
JavaScript does not support classes, but objects play a central role. Since there are no classes you may wonder 1) how are objects created, and 2) does JavaScript support inheritance? The short answers are: there are a few different ways to created objects and as far as inheritance, yes, JavaScript does support inheritance but through a mechanism that uses prototypes. The class-less, prototypal nature of JavaScript will be explored shortly, but first we'll review the types and objects supported by JavaScript.
First the basic types: JavaScript offers several primitive types: Numbers, String and Booleans, and also null type and undefined type. The first three, Numbers Strings, and Booleans, do have properties and methods but they are not objects. When reading a property or method from these types, JavaScript creates a wrapper object, by calling the Number(), String(), or Boolean() constructor behind the scenes. You can also explicitly create these wrapper objects yourself. Below is an example where JavaScript implicitly (i.e. behind the scenes) uses the String constructor to perform a substring operation. The second example uses the Number constructor to convert the number to a string while keeping only two decimals

var text = "excellent";
alert
(text.substring(0,5));     // => excel

var count = 20.1045;
alert
(count.toFixed(2));        // => 20.10

Objects
A JavaScript object is a collection of properties where each property has a name and a value. Just imagine it as a structure made up of key-value pairs. In more formal terms, JavaScript objects are associative arrays -- similar to Hash, Map, or Dictionary in other languages.
At runtime, you can create an empty object and then add properties of any type, such as primitive types, other objects, and functions to the object. Properties and values can be modified and deleted at any point in time. Properties can be enumerated using the for-in loop. Let's look at some examples:

// Note: the use of new Object() is generally discouraged
var o = new Object();

o
.firstName = "Joan";
o
.lastName = "Holland";
o
.age = 31;

alert
(o.firstName + " " + o.lastName);  // => Joan Holland
alert
(typeof o.age);                    // => number

delete o.firstName;
alert
(o.firstName + " " + o.lastName);  // => undefined Holland

for (var prop in o)
{
   
// name: firstName, value: Joan, type: string
   
// name: age, value: 31, type: number
    alert
("name: " + prop + " ,value: " + o[prop] +
         
" ,type: " + typeof o[prop]);
}
In this example an empty object is created. Then three properties are added by assigning two strings and a numeric value. After displaying the values and the number type, the firstName property is deleted. Finally, a for-in loop displays the remaining properties (with name, value, and type) on the object.
There are 3 categories of objects in JavaScript:

     1. Built-in (native) objects like Math, Date, and Array
     2. User-defined objects like Book, Employee, etc., and
     3. Host objects defined by the runtime environment (usually the browser) such as DOM objects
         and the window global object.

Objects in the first two categories conform to the EcmaScript specification. However, objects made available by the hosting environment are outside the realm of EcmaScript.

Functions
The code below confirms that functions are indeed objects in JavaScript

function say(name) {
   alert
("Hello " + name);
}

alert
(typeof say);             // => function
alert
(say instanceof Object);  // => true

say
.volume = "high";
alert
(say.volume);            // => high
The function is of type function, but it is also an instance of type Object. In the last two lines a property named volume is assigned to the object without a problem, confirming that it behaves like an object.
Functions can also be used to create objects; these are called constructor functions. First you declare a function and then assign properties and functions (i.e. methods) using the this keyword. This example assigns two properties and one method to this.

function Book (title, author) {
   
   
this.title = title;                      // book properties
   
this.author = author;
   
   
this.details = function() {              // book method 
       
return this.title + " by " + this.author;
   
}
}
By convention, constructor functions start with an upper-case letter (i.e. Book).
When a constructor function is called with a new operator it will create a new book instance. Internally, the function creates a new blank object and binds it to this. Then it executes the function body which commonly assigns properties and methods to this. At the end the function returns the newly created objects by an implicit return this statement.
In the code below a new Book instance is created and we invoke its details method:

var book = new Book("Ulysses", "James Joyce");

alert
(book.details());        // => Ulysses by James Joyce
Functions and objects are not the only objects in JavaScript; arrays are objects and regular expressions are objects also.
A property of an object can be another object, which in turn can have one or more objects. All these objects provide a lot of flexibility and allow the creation of complex tree and graph structures.
JavaScript is a prototype-based language
JavaScript has no classes, only objects. So, without classes, is there perhaps another way that objects can derive functionality from other objects? In other words, is inheritance supported by JavaScript? The answer is yes; you can achieve inheritance by using prototypes. This is called prototypal inheritance, a concept borrowed from a language named Self. Prototypal inheritance is implicit, meaning it exists even if you do nothing special.
Let's look at prototypal inheritance. Each object in JavaScript is linked to a prototype object from which it inherits properties and methods. The default prototype for an object is Object.prototype. You can access this property via a property called prototype. In the code below we have a constructor function and check its prototype property. This is the prototype object that will be assigned to each book instance that is created by this constructor function.

var Book = function(author) {
   
this.author = author;
};

alert
(Book.prototype);       // => [object Object], so there is something
Since each object has a prototype, it is easy to imagine a series of objects linked together to form a prototype chain. The beginning of the chain is the current object, linked to its prototype, which, in turn, is linked to its own prototype, etc. all the way until you reach the root prototype at Object.prototype.
Following the prototype chain is how a JavaScript object retrieves its properties and values. When evaluating an expression to retrieve a property, JavaScript determines if the property is defined in the object itself. If it is not found, it looks for the property in the immediate prototype up in the chain. This continues until the root prototype is reached. If the property is found, it is returned, otherwise undefined is returned
Every function in JavaScript automatically gets a prototype property including constructor function(s). When you use a function as a constructor, its prototype property is the object that will be assigned as the prototype to all instances created. Here is an example:

function Rectangle (width, height) {
   
this.width = width;
   
this.height = height;
}

Rectangle.prototype.area = function () {
   
return this.width * this.height;
};

var r1 = new Rectangle(4, 5);  
var r2 = new Rectangle(3, 4);  
alert
(r1.area());               // => 20
alert
(r2.area());               // => 12

In the example, r1 and r2 objects are created by the same constructor, so they both inherit from the same prototype which includes the area method.
There is considerable confusion surrounding prototypes and prototypal inheritance among JavaScript developers. Many books, blogs, and other references define prototypal inheritance but unfortunately most are rather fuzzy and lack clear code samples.







JavaScript's runtime and hosting environment
When JavaScript was first released the language was interpreted. The source code would be parsed and execute immediately without preliminary compilation into byte code. However, recent versions of browsers include highly optimized JavaScript compilers. Usually this involves the following steps: first it parses the script, checks the syntax, and produces byte code. Next, it takes the byte code as input, generates native (machine) code, and then executes it on the fly.
JavaScript applications need an environment to run in. The JavaScript interpreter/JIT-compiler is implemented as part of the host environment such as a web browser. The script is executed by the JavaScript engine of the web browser, which is by far the most common host environment for JavaScript.
More recently JavaScript is also being used outside the browser. Examples include Mozilla's Rhino and node.js – the latter is a Chrome-based platform to build fast, scalable network applications. JavaScript is also found on the desktop with applications like Open Office, Photoshop, Dreamweaver, and Illustrator, which allow scripting through JavaScript type languages.
JavaScript is a small language; it defines basic types, such as strings, numbers, and a few more advanced objects and concepts, such Math, Date, regular expressions, events, objects, functions, and arrays. However, JavaScript does not natively have the ability to receive input from the user and display output back to the user. Neither does it provide an API for graphics, networking, or storage. For this, it has to rely on its hosting environment. With JavaScript running in a browser, to communicate back and forth with the user, it needs to interact with the document object model, commonly known as the 'DOM'.
DOM is an internal representation of the HTML elements that appear in a web page. When the browser loads a page, it builds the page's DOM in memory and then displays the page. The HTML elements that represent the structure of a web page are called host objects that provide special access to the host environment. Based on user input, your JavaScript code modifies the DOM and as a consequence the web page is updated. Every piece of text, tag, attribute, and style can be accessed and manipulated using the DOM API. The document object lets you work with the DOM. A simple way to interact with the user is to use document.write which writes a message directly into the web page (note: the use of document.write is generally not recommended).

var today = new Date();
var day = today.getDay();
if (day === 0 || day === 6) {
    document
.write("It's weekend");
} else {
    document
.write("It's a weekday!");
}
Consider the following textbox on the web page:

<input id="email" type="text" />
Here is how you can access and change this element on the page:

var email = document.getElementById("email");     // gets ref to textbox
email
.disabled = true;                            // disable textbox

var address = "me@company.com";
document
.getElementById("email").value = address; // update value
When JavaScript runs in the browser, it makes a special object available called window which is the global object. Note that window is not part of the standard JavaScript language, but part of the hosting environment. The alert method of the window object is widely used to display messages in a dialog box in the web browser. Since window is a global object, JavaScript lets you use this method without prefixing it with the window object name and dot operator.
When JavaScript is not running on the browser an entirely different set of host objects will be made available by the hosting environment. For example, node.js which is hosted on server machines frequently interacts with HTTP request and response objects allowing the JavaScript program to generate web pages at runtime; indeed very different from the browser.

What's new in EcmaScript 5
EcmaScript is the official, standardized version of JavaScript and several well-known implementations exist, including JavaScript, Jscript (Microsoft) and ActionScript (Adobe).
EcmaScript version 5 (ES 5) was introduced in late 2009. This version adds some new features, such as getters and setters, which allow you to build useful shortcuts for accessing and changing data within an object (similar to C# properties). Also new is built-in support for JSON, with methods such as JSON.parse() and JSON.stringify(), removing the need to use external libraries to work with JSON.
In addition, ES 5 added "strict mode", a feature which aims to enforce a restricted variant of the language by providing thorough error checking and making the scripts less error-prone, simpler, more readable, and reliable. You enable strict mode, by adding "use strict"; as the first line to your script, like so:

"use strict";
var text = "Yes, I'm strict now!";
This will apply strict mode to the entire script. You need to be careful when concatenating different scripts from different sources, because strict mode will apply to all scripts and you may include script that was not meant to run in strict mode, which is very likely to cause errors.
To solve this you can limit the scope of strict mode to a function by including "use strict"; as the first line in the function body, like so

function f() {
   
"use strict";
    
...
}
Adding "use strict"; changes both syntax and runtime behavior. For example, strict mode prevents you from accidentally creating global variables by requiring that each variable is declared explicitly. If you forget to properly declare a variable you will get an error. For example, the following will not work:

"use strict";
x
= 4;             // error
function f() {
   
var a = 2;     
    b
= a;         // error
   
... 
}
Adding a var before x and before b will solve the issue.
Strict mode disallows (i.e. deprecates) certain undesirable features including the with() construct, the arguments.callee feature, and octal numbers; if it encounters any of these JavaScript will throw an error. Furthermore, the use of certain keywords is restricted; for instance virtually all attempts to use the keywords eval and arguments as variable or function names will throw an error.

var eval = 10;                 // error
function getArea(eval){}       // error
function eval(){}              // error
var arguments = [];            // error
Because of security concerns, the use of eval() is generally discouraged, but you can still use it (even in strict mode). In strict mode, the code passed to eval() will also be evaluated in strict mode. Furthermore, eval() does not let you introduce new variables which is considered risky because it may hide an existing function or global variable.

"use strict";
var code = "var num = 10;"
eval(code);             // variable creation not allowed
alert
(typeof num);      // undefined (some browsers return number)
Be aware that strict mode is currently not reliable implemented across all browsers, and, of course, older browsers don't support it at all. It is very important that you test your code with browsers that support it and those that don't. If it works in one it may not work in the other and vice versa.
An easy way to find out whether strict mode is supported is with the following expression:

(function() { "use strict"; return !this; })();
Here is how you use it:

var strict = (function() { "use strict"; return !this; })();

alert
(strict);  // => true or false
When strict is true you can assume strict mode is supported.
ES 5 has a new object model which provides great flexibility on how objects are manipulated and used. For example, objects allow getters and setters; they can prevent enumeration, deletion or manipulation of properties; and they can even block others from adding new properties.
Getters and setters are useful shortcuts to accessing and changing data values in an object. A getter is invoked when the value of the property is accessed (read). A setter is invoked when the value of the property is modified (write). The obvious advantage is that the 'private' name variable in the object is hidden from direct access. The syntax is rather awkward, but here is an example.

function Person(n){
   
var name = n;
    
   
this.__defineGetter__("name", function(){
        
return name;
   
});
    
   
this.__defineSetter__("name", function(val){
         name
= val;
   
});
}

var person = new Person("John");
alert
(person.name);     // => John              // uses getter

person
.name = "Mary";                           // uses setter
alert
(person.name);     // => Mary              // uses getter
In ES 5, each object property has several new attributes. They are: enumerable, writable, and configurable. With enumerable you indicate whether the property can be enumerated (using a for-in loop); writable indicates that a property is changeable, and configurable indicates whether it can be deleted or its other attributes can be changed.
Object.defineProperty is how you define these properties and their attributes. Below we are creating a car with 4 wheels. The attributes ensure that the wheels property cannot be changed or deleted, but wheel will show up when iterating over car's properties (with for-in).

var car = {};
 
Object.defineProperty(car, "wheels", {
   value
: 4,
   writable
: false,
   enumerable
: true,
   configurable
: false
});

car
.wheels = 3;               // => not allowed  (not writable)

for (var prop in car) {
   alert
(prop);               // => wheels       (enumerable)
}

delete car.wheels;            // => not allowed  (not configurable)
ES 5 provides two methods to control object extensibility:Object.preventExtensions prevents the addition of new properties to an object, and Object.isExtensible tells whether an object is extensible or not. The example below demonstrates their use:

var rectangle = {};
rectangle
.width = 10;                   
rectangle
.height = 20;                  

if (Object.isExtensible(rectangle)) {     // true
   
Object.preventExtensions(rectangle);  // disallow property additions
}

rectangle
.volume = 20;                    // not allowed
With ES 5 you have the ability to seal an object. A sealed object won't allow new properties to be added nor will it allow existing properties or its descriptors be changed. But it does allow reading and writing the property values. Two methods support this feature: Object.seal and Object.isSealed; the first one to seal the object, the second one to determine whether an object is sealed.

var employee = { firstName: "Jack", lastName: "Watson" };

Object.seal(employee);
alert
(Object.isSealed(employee));    // => true

employee
.firstName = "Tommie";       // okay
Freezing is equivalent to sealing, but disallows reading or writing property values. The two method involved are Object.freeze and Object.isFrozen:

var employee = { firstName: "Jack", lastName: "Watson" };

Object.freeze(employee);
alert
(Object.isFrozen(employee));    // => true

employee
.firstName = "Tommie";       // not allowed



Debugging JavaScript
Developers commonly use alert to print messages in a dialog box to help determine what is wrong in a certain part of their code. The statement below will show the total amount after the program has calculated the value.

var totalAmount = quantity * unitPrice;   // some computation
alert
("Amount is $", totalAmount);        // => Amount is $977.50
Clearly, alert as a debugging tool is very limited. First, it is only capable of displaying a simple string message and does not allow you to inspect more complex variables, such as arrays and objects. Secondly, it creates a modal window which prevents further interaction with the browser until the pop-up window is dismissed. This is particularly problematic when alert is placed in loops because you may end up having to close a large number of message boxes. Finally, there is a real risk that these messages are seen by end-users when the developer forgets to remove the alert before deployment.
Fortunately, more advanced debugging tools are now available. As an example we will review Firebug next.


Writing comments in JavaScript
In JavaScript a single line comment begins with a double slash //. All text to the right of it will be ignored by the compiler. This type of comment is typically used for quick notes about complex code or to temporarily remove a line of code (this is called 'commenting out').

var totalAmount;   // holds the quantity multiplied by unitPrice
A multi-line comment, also called block comment, begins with /* and ends with */. These are typically used to write comments that span multiple lines and also to comment out large blocks of code, possibly for debugging purposes.

/* Indicates the user role.
   The application has 3 predefined roles:
   1) Admin, 2) Guest, and 3) User (registered user)
*/

var userRole;
When using multi-line comments you need to be careful not to include the character combination */ as used in regular expressions. In the following two examples, syntax errors will be reported (notice that even our syntax highlighter is confused...).

/* Return the position of the match in the string 
   'JavaScript' which contains the string 'Jav'
   followed by the character 'a' any number of times.

   var position = 'JavaScript'.search(/Java*/
g);
*/

/
* Type comments were added
  
var IsSystemUser /*:Boolean*/ =  false;
  
var userCount /*:int*/ =  1;
*/
Because of the above risks, it is generally recommended you use // comments whenever possible.






Declaring JavaScript variables
Variables in JavaScript are declared with the var keyword. You have several options on structuring your variable declaration and initialization:

// declaring one variable
var cost;                   

// declaring multiple variables, delimited by commas
var cost, profit;           

// declaring and assigning one variable
var cost = 120;             

// declaring and assigning multiple variables
var cost = 120, profit = 77;
You can declare one variable at a time.
Let's look at variable naming rules. A variable name can contain any combination of alpha-numeric characters, the $ sign, and the underscore character. Its first character cannot be a digit. Variable names cannot contain space characters or any of the punctuation characters. Here are some examples of valid variable identifiers:

var _groupName_;
var $bicycle12;
var ABH;
var particle_X_Y;
var abc$123;
var easy;

Implied global variables
If a variable is not declared explicitly (using var), then JavaScript will automatically treat it as a global variable. This can hide misspelled and forgotten variable declarations and consequently introduce bugs in your program. This is demonstrated below. The variable count is missing a var and will be created implicitly. The variable reslt is a misspelling of 'result' and a new global variable named 'reslt' will be created. Worse, the original result value will always remain false.

count = 4;                 // => global count is created
var result = false;
if (condition === true) {
    reslt
= true;          // => global reslt is created!
}
As you can see, typos are not called out in JavaScript and can lead to subtle and hard-to-detect bugs.
JSLint uncovers implied global variables and requires that you declare them explicitly using the var keyword before they are assigned a value. Using var also improves program readability. Even if you use var, you still have to be careful when chaining declarations and assignments. In the following code all seems fine, but total is a local variable, but summary is an implied global.

function calculate() {
  
var total = summary = 0;   // => summary is implied global variable
  
...
}
The expression summary = 0 is evaluated first. Since summary is not declared, it is treated as global. The expression returns the value 0 which is further assigned to the variable total. Because total is declared with a var keyword, it is a local variable with function scope.

Variables as properties
When declaring a global variable, you are actually defining a property on the global object. If the global variable is created with var, the property that is created cannot be deleted (undefined) with the delete operator. On the other hand, implied globals can be deleted.

var a = 1;        // => explicit global
b
= 2;            // => implied global

delete a;         // => cannot delete
delete b;         // => deleted

Variable scoping
The scope of the variable determines its visibilityand its lifetime. Visibility determines the portions of the program in which it can be 'seen' and referenced. Lifetime is the period during execution of a program in which a variable or function exists
In programming, variable scoping is an important concept. JavaScript supports two scope-levels, global and functional, which are discussed next.

Global scope and function scope
In JavaScript, all variables that are defined outside functions are globally scoped; this means they are visible and accessible anywhere in the program. Variables that are defined inside a function have function scope, meaning they are only visible and accessible within the function, for the duration of that function.
In the example below variable g is global and is visible anywhere, including the function. The variables u and c are only visible within the function. It is said that variable g has global scope and variables u and c have function scope.

var g = "World";           // global scope

function countries() {
   
var u = "US";          // function scope
   
var c = "China";       // function scope

    alert
(g);              // => World
    alert
(u);              // => US
    alert
(c);              // => China
}
countries
();

alert
(g);                  // => World
alert
(typeof u);           // => undefined

The last line demonstrates the variable u is not visible outside the countries() function.

Function scope hides global scope
If you declare a local variable inside a function with the exact same name as a global variable, then the local variable will hide the global variable. In the next example, the local client variable hides the global client variable.

var client = "Joan";            // global

function getClient() {
  
var client = "Timothy";      // local, hides global
  
return client;
}

alert
(getClient());             // => "Timothy"


JavaScript does not support block scope
In C-like languages, when control enters a code block (for example an if statement enclosed by brackets), then local variables defined within the block will have their own execution context and are destroyed when the closing block brace is encountered. However, JavaScript does not support block-level scoping, only function and global level scoping.
In the example below, the client variable in the if-block refers to the global variable. There is no hiding or anything of that nature, just one global variable named client.

var client = "Joan";

if (true) {
  
var client = "Timothy";   // refers to global variable
   alert
(client);            // => "Timothy"
}

alert
(client);               // => "Timothy"


Looping variables
When using variables in for loops you have to be careful because they continue to exist outside the loop. In the example below, the for-statement creates the variable i which continues to exist outside the loop, even after the for-statement finishes execution. Most other languages that support block level scoping the looping variables cease to exist outside the for loop.

for (var i = 0; i < 5; i++) {
   
// do something
}

alert
(i);     // => 5


Variable and function hoisting
The JavaScript compiler invisibly moves (hoists) all the variables to the top of their containing scope. Consider this code:

function f() {
    doSomething
();
   
var count;
}
JavaScript transforms this code to this:

function f() {
   
var count;               // hoisted
    doSomething
();
}
All variables that you declare inside a function are visible throughout the function body (this is what we mean with function scope). This implies that variables are visible even before they are declared, but using a variable before it is initialized can lead to bugs. Here is an example:

var x = 1;
function f () {
    alert
(x);        // => undefined
   
var x = 2;
}
Notice we have a global variable x and a local variable x. The undefined result may surprise you. Perhaps you expected a value of 1 or possibly 2, but not undefined. It's all because of hoisting which involves the variable declaration, but does not include the assignment portion. Here is how the code executes:

var x = 1;
function f () {
   
var x;        // hoisted. hides global variable, but is unitialized.
    alert
(x);     // => undefined
    x
= 2;
}


Arithmetic and comparison operators
JavaScript comes with a set of operators you'd expect from any modern language. There are four categories: arithmetic, comparison, assignment, and logical.

Arithmetic Operators
Arithmetic operators perform basic computations on their operands (the variables they operate on). In the table below, variable a has a value of 2 before the operation is applied.

Operator
Operation
Expression
Result
+
Add
2 + a
4
-
Substract
2 - a
0
*
Multiply
3 * a
6
/
Divide
3 / a
1.5
%
Modulus - division remainder
7 % a
1
++
Increment - increase by 1
a++
3
--
Decrement - decrease by 1
a--
1

String Operators
The + operator is used for adding numeric values, but it can also be used to concatenate (join) two or more strings and return a single string. Here is an example:

var str1 = "Hello";
var str2 = " Vivek";
str1
= str1 + str2;        // => "Hello Vivek"
alert
(str1);
The last statement can also be rewritten by using the assignment += operator as follows:

var str1 = "Hello";
var str2 = " Vivek";
str1
+= str2;              // => "Hello Vivek"
alert
(str1);
Run
Comparison Operators
Comparison operators compare the value of two operands. If the comparison is true, they return true, otherwise false. In the table below the variables are: a = 1 and b = 2.

Operator
Operation
Expression
Result
==
Equal to
a == b
false
!=
Not equal to
a != b
true
<=
Less than equal to
a <= b
true
>=
Greater than or equal to
a >= b
false
Less than
a < b
true
Greater than
a > b
false
Assignment and boolean operators

Assignment Operators
In an assignment operation the value of a variable is computed from the expression that lies to the right of an assignment operator. That value is assigned to the variable or property that is on the left side of the operator. In the table below the variables have the following values:
a = 1, b = 2, and c = 3.

Operator
Operation
Result
=
a = b + c;
a = 5
+=
a += b;    // equivalent to a = a + b
a = 3
-=
a -= b;    // equivalent to a = a – b
a = -1
/=
a /= b;    // equivalent to a = a / b
a = 0.5
%=
c %= b;   // equivalent to c = c % b
c = 1
*=
a *= b;    // equivalent to a = a * b
a = 2

Logical or Boolean Operators
Logical or Boolean operators compare Boolean expressions and then return true or false. The && and || ('and' and 'or') operators take two operands. The ! ('not') operator takes a single operand. In the table below the variables have the following values: a = 1 and b = 2.

Operator
Operation
Expression
Result
&&
Logical and. Returns true only if both its first and second operands are evaluated to true.
a < 3 && b > 5
returns false as b > 5 is false
||
Logical or. Returns true if one of the two operands are evaluated to true, returns false if both are evaluated to true.
a < 3 || b > 5
returns true as a < 3 is true
!
Logical not. Unary operator that simply inverts the Boolean value of its operand.
!(b>5)
returns true




JavaScript keywords
Below are the JavaScript keywords. They cannot be used as variables, functions, or object identifiers.

 JavaScript Keywords



break
do
instanceof
typeof
case
else
new
var
catch
finally
return
void
continue
for
switch
while
debugger
function
this
with
default
if
throw

delete
in
try

In addition, the literals null, true, and false are reserved for their standard usage.
JavaScript reserved keywords
The EcmaScript specification has the following list of words reserved for future use. You should not use these as identifiers in your JavaScript code.

 JavaScript Reserved Keywords



class
implements
package
static
enum
import
private
super
export
interface
protected
yield
extends
let
public












No comments:

Post a Comment