[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 @title Javascript Object and Array 2 @group javascript 3 4 This document describes the behaviors of Object and Array in Javascript, and 5 a specific approach to their use which produces basically reasonable language 6 behavior. 7 8 = Primitives = 9 10 Javascript has two native datatype primitives, Object and Array. Both are 11 classes, so you can use ##new## to instantiate new objects and arrays: 12 13 COUNTEREXAMPLE 14 var a = new Array(); // Not preferred. 15 var o = new Object(); 16 17 However, **you should prefer the shorthand notation** because it's more concise: 18 19 lang=js 20 var a = []; // Preferred. 21 var o = {}; 22 23 (A possible exception to this rule is if you want to use the allocation behavior 24 of the Array constructor, but you almost certainly don't.) 25 26 The language relationship between Object and Array is somewhat tricky. Object 27 and Array are both classes, but "object" is also a primitive type. Object is 28 //also// the base class of all classes. 29 30 lang=js 31 typeof Object; // "function" 32 typeof Array; // "function" 33 typeof {}; // "object" 34 typeof []; // "object" 35 36 var a = [], o = {}; 37 o instanceof Object; // true 38 o instanceof Array; // false 39 a instanceof Object; // true 40 a instanceof Array; // true 41 42 43 = Objects are Maps, Arrays are Lists = 44 45 PHP has a single ##array## datatype which behaves like as both map and a list, 46 and a common mistake is to treat Javascript arrays (or objects) in the same way. 47 **Don't do this.** It sort of works until it doesn't. Instead, learn how 48 Javascript's native datatypes work and use them properly. 49 50 In Javascript, you should think of Objects as maps ("dictionaries") and Arrays 51 as lists ("vectors"). 52 53 You store keys-value pairs in a map, and store ordered values in a list. So, 54 store key-value pairs in Objects. 55 56 var o = { // Good, an object is a map. 57 name: 'Hubert', 58 species: 'zebra' 59 }; 60 61 console.log(o.name); 62 63 ...and store ordered values in Arrays. 64 65 var a = [1, 2, 3]; // Good, an array is a list. 66 a.push(4); 67 68 Don't store key-value pairs in Arrays and don't expect Objects to be ordered. 69 70 COUNTEREXAMPLE 71 var a = []; 72 a['name'] = 'Hubert'; // No! Don't do this! 73 74 This technically works because Arrays are Objects and you think everything is 75 fine and dandy, but it won't do what you want and will burn you. 76 77 = Iterating over Maps and Lists = 78 79 Iterate over a map like this: 80 81 lang=js 82 for (var k in object) { 83 f(object[k]); 84 } 85 86 NOTE: There's some hasOwnProperty nonsense being omitted here, see below. 87 88 Iterate over a list like this: 89 90 lang=js 91 for (var ii = 0; ii < list.length; ii++) { 92 f(list[ii]); 93 } 94 95 NOTE: There's some sparse array nonsense being omitted here, see below. 96 97 If you try to use ##for (var k in ...)## syntax to iterate over an Array, you'll 98 pick up a whole pile of keys you didn't intend to and it won't work. If you try 99 to use ##for (var ii = 0; ...)## syntax to iterate over an Object, it won't work 100 at all. 101 102 If you consistently treat Arrays as lists and Objects as maps and use the 103 corresponding iterators, everything will pretty much always work in a reasonable 104 way. 105 106 = hasOwnProperty() = 107 108 An issue with this model is that if you write stuff to Object.prototype, it will 109 show up every time you use enumeration ##for##: 110 111 COUNTEREXAMPLE 112 var o = {}; 113 Object.prototype.duck = "quack"; 114 for (var k in o) { 115 console.log(o[k]); // Logs "quack" 116 } 117 118 There are two ways to avoid this: 119 120 - test that ##k## exists on ##o## by calling ##o.hasOwnProperty(k)## in every 121 single loop everywhere in your program and only use libraries which also do 122 this and never forget to do it ever; or 123 - don't write to Object.prototype. 124 125 Of these, the first option is terrible garbage. Go with the second option. 126 127 = Sparse Arrays = 128 129 Another wrench in this mess is that Arrays aren't precisely like lists, because 130 they do have indexes and may be sparse: 131 132 var a = []; 133 a[2] = 1; 134 console.log(a); // [undefined, undefined, 1] 135 136 The correct way to deal with this is: 137 138 for (var ii = 0; ii < list.length; ii++) { 139 if (list[ii] == undefined) { 140 continue; 141 } 142 f(list[ii]); 143 } 144 145 Avoid sparse arrays if possible. 146 147 = Ordered Maps = 148 149 If you need an ordered map, you need to have a map for key-value associations 150 and a list for key order. Don't try to build an ordered map using one Object or 151 one Array. This generally applies for other complicated datatypes, as well; you 152 need to build them out of more than one primitive.
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |