JavaScript Tutorial 4: Objects and Arrays

Javascript tutorial  (学习笔记) 系列基本上翻译自 “A re-introduction to JavaScript (JS Tutorial)” 加上自己学习过程中的心得体会. 这一篇是第四篇(接Javascript Tutorial (学习笔记) 3):

Objects

JavaScript objects are simply collections of name-value pairs. As such, they are similar to:

  • Dictionaries in Python
  • Hashes in Perl and Ruby
  • Hash tables in C and C++
  • HashMaps in Java
  • Associative arrays in PHP

The fact that this data structure is so widely used is a testament to its versatility. Since everything (bar core types) in JavaScript is an object, any JavaScript program naturally involves a great deal of hash table lookups. It’s a good thing they’re so fast!

The “name” part is a JavaScript string, while the value can be any JavaScript value — including more objects. This allows you to build data structures of arbitrary complexity.

There are two basic ways to create an empty object:

var obj = new Object();

And:

var obj = {};

These are semantically equivalent; the second is called object literal syntax, and is more convenient. This syntax is also the core of JSON format and should be preferred at all times.

Once created, an object’s properties can again be accessed in one of two ways:

obj.name = "Simon";
var name = obj.name;

And…

obj["name"] = "Simon";
var name = obj["name"];

These are also semantically equivalent. The second method has the advantage that the name of the property is provided as a string, which means it can be calculated at run-time though using this method prevents some JavaScript engine and minifier optimizations being applied. It can also be used to set and get properties with names that are reserved words:

obj.for = "Simon"; // Syntax error, because 'for' is a reserved word
obj["for"] = "Simon"; // works fine

Object literal syntax can be used to initialise an object in its entirety:

var obj = {
    name: "Carrot",
    "for": "Max",
    details: {
        color: "orange",
        size: 12
    }
}

Attribute access can be chained together:

> obj.details.color
orange
> obj["details"]["size"]
12
总结: object就是一个map, 可以定义一系列的key-value pair. 

Arrays

Arrays in JavaScript are actually a special type of object. They work very much like regular objects (numerical properties can naturally be accessed only using [] syntax) but they have one magic property called ‘length‘. This is always one more than the highest index in the array.

The old way of creating arrays is as follows:

> var a = new Array();
> a[0] = "dog";
> a[1] = "cat";
> a[2] = "hen";
> a.length
3

A more convenient notation is to use an array literal:

> var a = ["dog", "cat", "hen"];
> a.length
3

Leaving a trailing comma at the end of an array literal is inconsistent across browsers, so don’t do it.

Note that array.length isn’t necessarily the number of items in the array. Consider the following:

> var a = ["dog", "cat", "hen"];
> a[100] = "fox";
> a.length
101

Remember — the length of the array is one more than the highest index.

If you query a non-existent array index, you get undefined:

> typeof a[90]
undefined

If you take the above into account, you can iterate over an array using the following:

for (var i = 0; i < a.length; i++) {
    // Do something with a[i]
}

This is slightly inefficient as you are looking up the length property once every loop. An improvement is this:

for (var i = 0, len = a.length; i < len; i++) {
    // Do something with a[i]
}

An even nicer idiom is:

for (var i = 0, item; item = a[i++];) {
    // Do something with item
}

Here we are setting up two variables. The assignment in the middle part of the for loop is also tested for truthfulness — if it succeeds, the loop continues. Since i is incremented each time, items from the array will be assigned to item in sequential order. The loop stops when a “falsy” item is found (such as undefined).

Note that this trick should only be used for arrays which you know do not contain “falsy” values (arrays of objects or DOM nodes for example). If you are iterating over numeric data that might include a 0 or string data that might include the empty string you should use the i, len idiom instead.

Another way to iterate is to use the <a title="en/Core_JavaScript_1.5_Reference/Statements/for...in" href="https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in" target="_blank">for...in</a> loop. Note that if someone added new properties to Array.prototype, they will also be iterated over by this loop:

for (var i in a) {
  // Do something with a[i]
}
到这里为止做一个小的测试:
var a = ["dog", "cat", "hen"];
a[100] = "fox";
console.log("a.length = " + a.length); //101

console.log("---------> test regular for loop: ")
for (var i = 0, len = a.length; i < len; i++) {
    // Do something with a[i]
    console.log("item = " + a[i]);
} //输出101个, 中间全是undefined

console.log("---------> test nicer regular for loop: ")
for (var i = 0, item; item = a[i++];) {
    // Do something with item
    console.log("item = " + item);
}//只会输出前面三个item

console.log("--------> test for(x in a) for array");
for(x in a) {
    console.log("item = " + a[x]);
}//输出所有的四个item, 注意x这里是key

console.log("--------> test for(x in a) for object");
var person={fname:"John",lname:"Doe",age:25};

for (x in person)
{
    console.log("x = " + x);
    console.log("v = " + person[x]);
} //x is the key in person

/*
   a.length = 101
   ---------> test regular for loop:
   item = dog
   item = cat
   item = hen
   item = undefined
   ... ...
   item = undefined
   item = fox
   ---------> test nicer regular for loop:
   item = dog
   item = cat
   item = hen
   --------> test for(x in a) for array
   item = dog
   item = cat
   item = hen
   item = fox
   --------> test for(x in a) for object
   x = fname
   v = John
   x = lname
   v = Doe
   x = age
   v = 25
*/

If you want to append an item to an array, the safest way to do it is like this:

a[a.length] = item;                 // same as a.push(item);

Since a.length is one more than the highest index, you can be assured that you are assigning to an empty position at the end of the array.

Arrays come with a number of methods:

Method name Description
a.toString()
a.toLocaleString()
a.concat(item[, itemN]) Returns a new array with the items added on to it.
a.join(sep)  Joins all elements of an array into a string (seprated by ‘sep’)
a.pop() Removes and returns the last item.
a.push(item[, itemN]) Push adds one or more items to the end.
a.reverse()
a.shift()  Removes the first element of an array, and returns that element
a.slice(start, end) Returns a sub-array.
a.sort([cmpfn]) Takes an optional comparison function.
a.splice(start, delcount[, itemN]) Lets you modify an array by deleting a section and replacing it with more items.
a.unshift([item]) Prepends items to the start of the array. (Adds new elements to the beginning of an array, and returns the new length)
Written on August 27, 2013