Dapeng Li

Hungry, foolish and passionate – yet another software developer.

Just Enough JavaScript – Variable Scope and Object

leave a comment

This is the first post on Just Enough JavaScript, we’ll cover variable scope and object.

Variable Scope 1

Global variables, local variables

In your program, the scope of a variable is the region within which that variable is valid.

Based on the scope, there are two types of variables in JavaScript: global variables and local variables. Global variables are accessible from everywhere in your code; local variables are only accessible within the function it’s defined.

// ex_1.1
// global_variables_local_variables

var global = "global";  // this is a global variable, visible in everywhere

function myFunc(param) {  // function argument has the same scope as local variable
	var local = "local";  // this is a local variable, visible in myFunc
}

Within a function, a local variable takes precedence over a global variable with the same name.

// ex_1.2
// local_variables_shadow_global_variables

var scope = "global";  // a global variable

function myFunc() {
	var scope = "local";  // scope variable will has the value "local" inside myFunc
	console.log(scope);  // "local"
}

myFunc();  // "local"
console.log(scope);  // "global"

Accessing a variable declared but not initialized with return undefined, accessing a variable not declared will cause a ReferenceError.

// ex_1.3
// variable_undefined

var variable = "global";
console.log(variable);  // "global"

function myFunc() {
	var mysteryVariable;  // declare variable, but doesn't initialize

	console.log(mysteryVariable);  // undefined
	console.log(anotherMysteryVariable);  // ReferenceError: anotherMysteryVariable is not defined
}

myFunc();

Only function scope, no block scope

Some other languages have block scope, where code inside curly braces has its own scope, JavaScript doesn’t have block scope.

The only way to create a scope in JavaScript is to define a function, JavaScript only has function scope.

Because of the lack of block scope, you should be aware of variable scopes when using curly braces.

// ex_1.4
// function_scope

function test(o) {
	var i = 0;  // i is defined throughout function

	if (typeof o === "object") {
		var j = 0;  // j is defined everywhere, not just block

		for (var k = 0; k < 10; k++) {  // k is defined everywhere, not just loop
			console.log(k);  // print numbers 0 through 9
		}

		console.log(k);  // k is still defined: prints 10
	}

	console.log(j);  // j is defined, but may not be initialized
}

In the example above, variable i, j and k are all in the same scope.

Hoisting

In example 1.4, it’s as if variable i, j and k were declared in the first line of function – being hoisted to the top of function. Just like this:

// ex_1.5
// function_scope_hoisting

function test(o) {
	var i = 0, j, k; // declaration of j and k are hoisted to the beginning of function

	if (typeof o === "object") {
		j = 0;

		for (k = 0; k < 10; k++) {
			console.log(k);
		}

		console.log(k);
	}

	console.log(j);
}

Another effect of hoisting is sometimes a variable can be accessed before it’s declared, consider the following example.

// ex_1.6
// hoisting_puzzle

var scope = "global";

function f() {
	console.log(scope); // Prints "undefined", not "global"
	var scope = "local"; // Variable initialized here, but defined everywhere
	console.log(scope); // Prints "local"
}

f();

Although variable scope was declared in line 8, because of the hoisting effect, it can be accessed in line 7. It’s as if it’s declared like this:

// ex_1.7
// hoisting_puzzle2

function f() {
	var scope; // Local variable is declared at the top of the function
	console.log(scope); // It exists here, but still has "undefined" value
	scope = "local"; // Now we initialize it and give it a value
	console.log(scope); // And here it has the value we expect
}

Because JavaScript doesn’t have block scope, it’s a good practice to declare all of the variables used in a function at the top of the function body. Just like the code in example 1.5.

Use var keyword

JavaScript is a dynamic typed language, so you don’t specify the type of your variable in declaration, you can just use the var keyword.

It’s a good practice to always use the var keyword in variable declaration, if you don’t specify the var keyword, that variable will be declared in global scope.

// ex_1.8
// var_keyword

scope = "global";  // Declare a global variable, even without var.

function checkscope2() {
	scope = "local";  // Oops! We just changed the global variable.
	myscope = "local";  // This implicitly declares a new global variable.
	return [scope, myscope]; // Return two values.
}

checkscope2();  // => ["local", "local"]: has side effects!
console.log(scope);  // "local": global variable has changed.
console.log(myscope);  // "local": global namespace cluttered up.

Lexical scoping

In JavaScript, a variable is visible throughout the function in which it’s declared (thus the name “function scope”), and also within any functions nested within that function.

JavaScript is a lexically scoped language, means functions are executed using the variable scope that was in effect when they were defined, not the variable scope that is in effect when they are invoked.

These two characteristics will lead to an important concept named closure, when you’re considering a function and the environment under which that function was invoked. We will visit closure in next post on functions.

Object 2

In JavaScript, objects are mutable keyed collections. 3

Creating new objects – Object Literal

Create JavaScript objects with the object literal syntax: a pair of curly braces surrounding zero or more name/value pairs.

// ex_1.9
// object_literal

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 values

var book = {
	"main title": "JavaScript",  // Property names include spaces,
	'sub-title': "The Definitive Guide",  // and hyphens, so use string literals
	"for": "all audiences",  // for is a reserved word, so quote
	author: {  // The value of this property is
		firstname: "David",  // itself an object. Note that
		surname: "Flanagan"  // these property names are unquoted.
	}
};

Creating new objects – with Constructor

Use new operator to invoke a function to create an object. That function is usually called constructor, code in the constructor function will initialize the newly created object. Constructor also determines the prototype of the newly created object, we’ll review prototype in a later post on prototype and inheritance.

// ex_1.10
// constructor

var o = new Object();  // Create an empty object: same as {}.
var a = new Array();  // Create an empty array: same as [].

function MyType() {  // MyType is a constructor
	// code to initialize new object
}

var myInstance = new MyType();  // create an instance of MyType

Retrieval/Update/Delete

Values in an object can be retrieved with the [] suffix. Like retrieving a value in a hash. If the key is a legal JavaScript name and not a reserved word, then we can use the . notation.

Accessing a non-existent property of object will return undefined.

// ex_1.11
// object_properties

var book = {
	"main title": "JavaScript",
	'sub-title': "The Definitive Guide",
	"for": "all audiences",
	author: {
		firstname: "David",
		surname: "Flanagan"
	}
};

// Get
var name = book.author.surname;  // Get the "surname" property of the author property.
var title = book["main title"];  // Get the "main title" property of the book.
var unknown = book.mystery_chapter;  // accessing a property not exist will return undefined

// Update
book.edition = 6;  // Create an "edition" property of book.
book["main title"] = "ECMAScript";  // Set the "main title" property.

// Delete
delete book.author;  // The book object now has no author property.
delete book["main title"];  // Now it doesn't have "main title", either.

Add new properties/functions

Setting a value to a property doesn’t exist in an object will cause that property be created.

// ex_1.12
// object_properties_augment

var obj = {};  // create a new object

obj.newProperty = 15;  // create a new property named newProperty

console.log(obj.newProperty);  // 15

Equality test 4

Douglas Crockford recommends using === and !== operators for equality test. If the values being compared are of the same type and same value, === will return true and !== will return false.

Avoid using their “evil twins” (== and !=), which will try to coerce when the values being compared are of different types.

OK, that’s a quick tour of Variable Scope and Object in JavaScript. We’ll see functions upcoming next.


1. More details from page 53 in the book JavaScript: The Definitive Guide, 6th Edition by David Flanagan, Amazon Link

2. More details from page 115 in the book JavaScript: The Definitive Guide, 6th Edition by David Flanagan, Amazon Link

3. More details from page 20 in the book JavaScript: The Good Parts by Douglas Crockford, Amazon Link

4. More details from page 109 in the book JavaScript: The Good Parts by Douglas Crockford, Amazon Link

Written by Dapeng

May 15th, 2012 at 9:38 pm

Posted in Programming

Tagged with