Compare Revisions

A re-introduction to JavaScript (JS Tutorial)

Revision 345153:

Revision 345153 by ozzydevil on

Revision 345255:

Revision 345255 by Moyogo on

Title:
SpecialPowers
SpecialPowers
Slug:
JavaScript/A_re-introduction_to_JavaScript
JavaScript/A_re-introduction_to_JavaScript
Content:

Revision 345153
Revision 345255
nn7    <h2 id="Introduction">
8      Introduction
7    <p>9    </h2>
8      &nbsp;
9    </p>10    <p>
11      Why a re-introduction? Because <a href="/en/JavaScript" tit
 >le="en/JavaScript">JavaScript</a> has a reasonable claim to being
 > <a class="external" href="http://javascript.crockford.com/javasc
 >ript.html">the world's most misunderstood programming language</a
 >>. While often derided as a toy, beneath its deceptive simplicity
 > lie some powerful language features. 2005 saw the launch of a nu
 >mber of high-profile JavaScript applications, showing that deeper
 > knowledge of this technology is an important skill for any web d
 >eveloper.
10    <p>12    </p>
11      SpecialPowers is a set of APIs available to&nbsp;<a href="/
>en/Mochitest" title="en/Mochitest">Mochitest</a>&nbsp;tests. Moch 
>itests are intended to be written like regular web pages. However 
>, sometimes tests need to do things that regular web pages are no 
>t permitted to do for security reasons. In these cases, the Speci 
>alPowers APIs can be used to perform specific actions outside of  
>the reach of normal web pages. 
12    </p>13    <p>
14      It's useful to start with an idea of the language's history
 >. JavaScript was created in 1995 by Brendan Eich, an engineer at 
 >Netscape, and first released with Netscape 2 early in 1996. It wa
 >s originally going to be called LiveScript, but was renamed in an
 > ill-fated marketing decision to try to capitalize on the popular
 >ity of Sun Microsystem's Java language — despite the two having v
 >ery little in common. This has been a source of confusion ever si
 >nce.
15    </p>
16    <p>
17      Microsoft released a mostly-compatible version of the langu
 >age called JScript with IE 3 several months later. Netscape submi
 >tted the language to <a class="external" href="http://www.ecma-in
 >ternational.org/">Ecma International</a>, a European standards or
 >ganization, which resulted in the first edition of the <a href="/
 >en/JavaScript/Language_Resources" title="en/ECMAScript">ECMAScrip
 >t</a> standard in 1997. The standard received a significant updat
 >e as <a class="external" href="http://www.ecma-international.org/
 >publications/standards/Ecma-262.htm">ECMAScript edition 3</a> in 
 >1999, and has stayed pretty much stable ever since. The fourth ed
 >ition was abandoned, due to political differences concerning lang
 >uage complexity. Many parts of the fourth edition formed a basis 
 >of the new ECMAScript edition 5, published in December of 2009.
18    </p>
19    <p>
20      This stability is great news for developers, as it's given 
 >the various implementations plenty of time to catch up. I'm going
 > to focus almost exclusively on the edition 3 dialect. For famili
 >arity, I will stick with the term JavaScript throughout.
21    </p>
22    <p>
23      Unlike most programming languages, the JavaScript language 
 >has no concept of input or output. It is designed to run as a scr
 >ipting language in a host environment, and it is up to the host e
 >nvironment to provide mechanisms for communicating with the outsi
 >de world. The most common host environment is the browser, but Ja
 >vaScript interpreters can also be found in Adobe Acrobat, Photosh
 >op, Yahoo!'s Widget engine, and even server side environments.
24    </p>
25    <h2 id="Overview">
26      Overview
27    </h2>
28    <p>
29      JavaScript is an object oriented dynamic language; it has t
 >ypes and operators, core objects, and methods. Its syntax comes f
 >rom the Java and C languages, so many structures from those langu
 >ages apply to JavaScript as well. One of the key differences is t
 >hat JavaScript does not have classes; instead, the class function
 >ality is accomplished by object prototypes. The other main differ
 >ence is that functions are objects, giving functions the capacity
 > to hold executable code and be passed around like any other obje
 >ct.
30    </p>
31    <p>
32      Let's start off by looking at the building block of any lan
 >guage: the types. JavaScript programs manipulate values, and thos
 >e values all belong to a type. JavaScript's types are:
33    </p>
34    <ul>
35      <li>
36        <a href="/En/Core_JavaScript_1.5_Reference/Global_Objects
 >/Number" title="en/Core_JavaScript_1.5_Reference/Global_Objects/N
 >umber">Numbers</a>
37      </li>
38      <li>
39        <a href="/En/Core_JavaScript_1.5_Reference/Global_Objects
 >/String" title="en/Core_JavaScript_1.5_Reference/Global_Objects/S
 >tring">Strings</a>
40      </li>
41      <li>
42        <a href="/en/JavaScript/Reference/Global_Objects/Boolean"
 > title="en/Core_JavaScript_1.5_Reference/Global_Objects/Boolean">
 >Booleans</a>
43      </li>
44      <li>
45        <a href="/en/JavaScript/Reference/Global_Objects/Function
 >" title="en/Core_JavaScript_1.5_Reference/Global_Objects/Function
 >">Functions</a>
46      </li>
47      <li>
48        <a href="/en/JavaScript/Reference/Global_Objects/Object" 
 >title="en/Core_JavaScript_1.5_Reference/Global_Objects/Object">Ob
 >jects</a>
49      </li>
50    </ul>
51    <p>
52      ... oh, and Undefined and Null, which are slightly odd. And
 > <a href="/en/JavaScript/Reference/Global_Objects/Array" title="e
 >n/Core_JavaScript_1.5_Reference/Global_Objects/Array">Arrays</a>,
 > which are a special kind of object. And <a href="/en/JavaScript/
 >Reference/Global_Objects/Date" title="en/Core_JavaScript_1.5_Refe
 >rence/Global_Objects/Date">Dates</a> and <a href="/en/JavaScript/
 >Reference/Global_Objects/RegExp" title="en/Core_JavaScript_1.5_Re
 >ference/Global_Objects/RegExp">Regular Expressions</a>, which are
 > objects that you get for free. And to be technically accurate, f
 >unctions are just a special type of object. So the type diagram l
 >ooks more like this:
53    </p>
54    <ul>
55      <li>Number
56      </li>
57      <li>String
58      </li>
59      <li>Boolean
60      </li>
61      <li>Object
62        <ul>
63          <li>Function
64          </li>
65          <li>Array
66          </li>
67          <li>Date
68          </li>
69          <li>RegExp
70          </li>
71        </ul>
72      </li>
73      <li>Null
74      </li>
75      <li>Undefined
76      </li>
77    </ul>
78    <p>
79      And there are some built in <a href="/en/JavaScript/Referen
 >ce/Global_Objects/Error" title="en/Core_JavaScript_1.5_Reference/
 >Global_Objects/Error">Error</a> types as well. Things are a lot e
 >asier if we stick with the first diagram, though.
80    </p>
81    <h2 id="Numbers">
82      Numbers
83    </h2>
84    <p>
85      Numbers in JavaScript are "double-precision 64-bit format I
 >EEE 754 values", according to the spec. This has some interesting
 > consequences. There's no such thing as an integer in JavaScript,
 > so you have to be a little careful with your arithmetic if you'r
 >e used to math in C or Java. Watch out for stuff like:
86    </p>
87    <pre class="eval">
880.1 + 0.2 == 0.30000000000000004
89</pre>
90    <p>
91      In practice, integer values are treated as 32-bit ints (and
 > are stored that way in some browser implementations), which can 
 >be important for bit-wise operations. For details, see <a class="
 >external" href="http://www.hunlock.com/blogs/The_Complete_Javascr
 >ipt_Number_Reference" title="http://www.hunlock.com/blogs/The_Com
 >plete_Javascript_Number_Reference">The Complete JavaScript Number
 > Reference</a>.
92    </p>
93    <p>
94      The standard <a href="/en/JavaScript/Reference/Operators/Ar
 >ithmetic_Operators" title="en/Core_JavaScript_1.5_Reference/Opera
 >tors/Arithmetic_Operators">numeric operators</a> are supported, i
 >ncluding addition, subtraction, modulus (or remainder) arithmetic
 > and so forth. There's also a built-in object that I forgot to me
 >ntion earlier called <a href="/en/JavaScript/Reference/Global_Obj
 >ects/Math" title="en/Core_JavaScript_1.5_Reference/Global_Objects
 >/Math">Math</a> to handle more advanced mathematical functions an
 >d constants:
95    </p>
96    <pre class="brush: js">
97Math.sin(3.5);
98var d = Math.PI * r * r;
99</pre>
100    <p>
101      You can convert a string to an integer using the built-in <
 >code><a href="/en/JavaScript/Reference/Global_Objects/parseInt" t
 >itle="en/Core_JavaScript_1.5_Reference/Global_Functions/parseInt"
 >>parseInt()</a></code> function. This takes the base for the conv
 >ersion as an optional second argument, which you should always pr
 >ovide:
102    </p>
103    <pre class="brush: js">
104&gt; parseInt("123", 10)
105123
106&gt; parseInt("010", 10)
10710
108</pre>
109    <p>
110      If you don't provide the base, you can get surprising resul
 >ts:
111    </p>
112    <pre class="brush: js">
113&gt; parseInt("010")
1148
115</pre>
116    <p>
117      That happened because the <code>parseInt</code> function de
 >cided to treat the string as octal due to the leading 0.
118    </p>
119    <p>
120      If you want to convert a binary number to an integer, just 
 >change the base:
121    </p>
122    <pre class="brush: js">
123&gt; parseInt("11", 2)
1243
125</pre>
126    <p>
127      Similarly, you can parse floating point numbers using the b
 >uilt-in <code><a href="/en/JavaScript/Reference/Global_Objects/pa
 >rseFloat" title="en/JavaScript/Reference/Global Objects/parseFloa
 >t">parseFloat()</a></code> function which uses base 10 always unl
 >ike its <a href="/en/JavaScript/Reference/Global_Objects/parseInt
 >" title="en/JavaScript/Reference/Global Objects/parseInt"><code>p
 >arseInt()</code></a> cousin.
128    </p>
129    <p>
130      You can also use the unary <code>+</code> operator to conve
 >rt values to numbers:
131    </p>
132    <pre>
133&gt; + "42"
13442 
135</pre>
136    <p>
137      A special value called <code><a href="/en/JavaScript/Refere
 >nce/Global_Objects/NaN" title="en/Core_JavaScript_1.5_Reference/G
 >lobal_Properties/NaN">NaN</a></code> (short for "Not a Number") i
 >s returned if the string is non-numeric:
138    </p>
139    <pre class="brush: js">
140&gt; parseInt("hello", 10)
141NaN
142</pre>
143    <p>
144      <code>NaN</code> is toxic: if you provide it as an input to
 > any mathematical operation the result will also be <code>NaN</co
 >de>:
145    </p>
146    <pre class="brush: js">
147&gt; NaN + 5
148NaN
149</pre>
150    <p>
151      You can test for <code>NaN</code> using the built-in <code>
 ><a href="/en/JavaScript/Reference/Global_Objects/isNaN" title="en
 >/Core_JavaScript_1.5_Reference/Global_Functions/isNaN">isNaN()</a
 >></code> function:
152    </p>
153    <pre class="brush: js">
154&gt; isNaN(NaN)
155true
156</pre>
157    <p>
158      JavaScript also has the special values <code><a href="/en/J
 >avaScript/Reference/Global_Objects/Infinity" title="en/Core_JavaS
 >cript_1.5_Reference/Global_Properties/Infinity">Infinity</a></cod
 >e> and <code>-Infinity</code>:
159    </p>
160    <pre class="brush: js">
161&gt; 1 / 0
162Infinity
163&gt; -1 / 0
164-Infinity
165</pre>
166    <p>
167      You can test for <code>Infinity</code>, <code>-Infinity</co
 >de> and <code>NaN</code> values using the built-in <code><a href=
 >"/en/JavaScript/Reference/Global_Objects/isFinite" title="en/Core
 >_JavaScript_1.5_Reference/Global_Functions/isFinite">isFinite()</
 >a></code> function:
168    </p>
169    <pre class="brush: js">
170&gt; isFinite(1/0)
171false
172&gt; isFinite(-Infinite)
173false
174&gt; isFinite(NaN)
175false
176</pre>
n14      If your Mochitest needs to perform a wide range of privilegn178      <strong>Note:</strong> The <a href="/en/JavaScript/Referenc
>ed actions, it should probably be a&nbsp;<a href="/en/Chrome_test>e/Global_Objects/parseInt" title="en/JavaScript/Reference/Global 
>s" title="en/Chrome tests">Chrome Mochitest</a>&nbsp;instead.>Objects/parseInt"><code>parseInt()</code></a> and <code><a href="
 >/en/JavaScript/Reference/Global_Objects/parseFloat" title="en/Jav
 >aScript/Reference/Global Objects/parseFloat">parseFloat()</a></co
 >de> functions parse a string until they reach a character that is
 >n't valid for the specified number format, then return the number
 > parsed up to that point. However the "+" operator simply convert
 >s the string to <code>NaN</code> if there is any invalid characte
 >r in it. Just try parsing the string "10.2abc" with each method b
 >y yourself in the console and you'll understand the differences b
 >etter.
n16    <h2 id="Existing_APIs">n180    <h2 id="Strings">
17      Existing APIs181      Strings
182    </h2>
183    <p>
184      Strings in JavaScript are sequences of characters. More acc
 >urately, they're sequences of <a href="/en/JavaScript/Guide/Obsol
 >ete_Pages/Unicode" title="en/Core_JavaScript_1.5_Guide/Unicode">U
 >nicode characters</a>, with each character represented by a 16-bi
 >t number. This should be welcome news to anyone who has had to de
 >al with internationalisation.
18    </h2>185    </p>
19    <h3 id="SpecialPowers.sanityCheck()">186    <p>
20      SpecialPowers.sanityCheck()187      If you want to represent a single character, you just use a
 > string of length 1.
188    </p>
189    <p>
190      To find the length of a string, access its <code><a href="/
 >en/JavaScript/Reference/Global_Objects/String/length" title="en/C
 >ore_JavaScript_1.5_Reference/Global_Objects/String/length">length
 ></a></code> property:
191    </p>
192    <pre class="brush: js">
193&gt; "hello".length
1945
195</pre>
196    <p>
197      There's our first brush with JavaScript objects! Did I ment
 >ion that strings are objects too? They have <a href="/En/Core_Jav
 >aScript_1.5_Reference/Global_Objects/String#Methods" title="en/Co
 >re_JavaScript_1.5_Reference/Global_Objects/String#Methods">method
 >s</a> as well:
198    </p>
199    <pre class="brush: js">
200&gt; "hello".charAt(0)
201h
202&gt; "hello, world".replace("hello", "goodbye")
203goodbye, world
204&gt; "hello".toUpperCase()
205HELLO
206</pre>
207    <h2 id="Other_types">
208      Other types
209    </h2>
210    <p>
211      JavaScript distinguishes between <code>null</code>, which i
 >s an object of type 'object' that indicates a deliberate non-valu
 >e, and <code>undefined</code>, which is an object of type 'undefi
 >ned' that indicates an uninitialized value — that is, a value has
 >n't even been assigned yet. We'll talk about variables later, but
 > in JavaScript it is possible to declare a variable without assig
 >ning a value to it. If you do this, the variable's type is <code>
 >undefined</code>.
212    </p>
213    <p>
214      JavaScript has a boolean type, with possible values <code>t
 >rue</code> and <code>false</code> (both of which are keywords). A
 >ny value can be converted to a boolean according to the following
 > rules:
215    </p>
216    <ol>
217      <li>
218        <code>false</code>, <code>0</code>, the empty string (<co
 >de>""</code>), <code>NaN</code>, <code>null</code>, and <code>und
 >efined</code> all become <code>false</code>
219      </li>
220      <li>all other values become <code>true</code>
221      </li>
222    </ol>
223    <p>
224      You can perform this conversion explicitly using the <code>
 >Boolean()</code> function:
225    </p>
226    <pre class="brush: js">
227&gt; Boolean("")
228false
229&gt; Boolean(234)
230true
231</pre>
232    <p>
233      However, this is rarely necessary, as JavaScript will silen
 >tly perform this conversion when it expects a boolean, such as in
 > an <code>if</code> statement (see below). For this reason, we so
 >metimes speak simply of "true values" and "false values," meaning
 > values that become <code>true</code> and <code>false</code>, res
 >pectively, when converted to booleans. Alternatively, such values
 > can be called "truthy" and "falsy", respectively.
234    </p>
235    <p>
236      Boolean operations such as <code>&amp;&amp;</code> (logical
 > <em>and</em>), <code>||</code> (logical <em>or</em>), and <code>
 >!</code> (logical <em>not</em>) are supported; see below.
237    </p>
238    <h2 id="Variables">
239      Variables
240    </h2>
241    <p>
242      New variables in JavaScript are declared using the <code><a
 > href="/en/JavaScript/Reference/Statements/var" title="en/Core_Ja
 >vaScript_1.5_Reference/Statements/var">var</a></code> keyword:
243    </p>
244    <pre class="brush: js">
245var a;
246var name = "simon";
247</pre>
248    <p>
249      If you declare a variable without assigning any value to it
 >, its type is <code>undefined</code>.&nbsp;
250    </p>
251    <p>
252      An important difference from other languages like Java is t
 >hat in JavaScript, blocks do not have scope; only functions have 
 >scope. So if a variable is defined using <code>var</code> in a co
 >mpound statement (for example inside an <code>if</code> control s
 >tructure), it will be visible to the entire function.
253    </p>
254    <h2 id="Operators">
255      Operators
256    </h2>
257    <p>
258      JavaScript's numeric operators are <code>+</code>, <code>-<
 >/code>, <code>*</code>, <code>/</code> and <code>%</code> - which
 > is the remainder operator. Values are assigned using <code>=</co
 >de>, and there are also compound assignment statements such as <c
 >ode>+=</code> and <code>-=</code>. These extend out to <code>x = 
 >x <em>operator</em> y</code>.
259    </p>
260    <pre class="brush: js">
261x += 5
262x = x + 5
263</pre>
264    <p>
265      You can use <code>++</code> and <code>--</code> to incremen
 >t and decrement respectively. These can be used as prefix or post
 >fix operators.
266    </p>
267    <p>
268      The <a href="/en/JavaScript/Reference/Operators/String_Oper
 >ators" title="en/Core_JavaScript_1.5_Reference/Operators/String_O
 >perators"><code>+</code> operator</a> also does string concatenat
 >ion:
269    </p>
270    <pre class="brush: js">
271&gt; "hello" + " world"
272hello world
273</pre>
274    <p>
275      If you add a string to a number (or other value) everything
 > is converted in to a string first. This might catch you out:
276    </p>
277    <pre class="brush: js">
278&gt; "3" + 4 + 5
279345
280&gt; 3 + 4 + "5"
28175
282</pre>
283    <p>
284      Adding an empty string to something is a useful way of conv
 >erting it.
285    </p>
286    <p>
287      <a href="/en/JavaScript/Reference/Operators/Comparison_Oper
 >ators" title="en/Core_JavaScript_1.5_Reference/Operators/Comparis
 >on_Operators">Comparisons</a> in JavaScript can be made using <co
 >de>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code> and <code>&
 >gt;=</code>. These work for both strings and numbers. Equality is
 > a little less straightforward. The double-equals operator perfor
 >ms type coercion if you give it different types, with sometimes i
 >nteresting results:
288    </p>
289    <pre class="brush: js">
290&gt; "dog" == "dog"
291true
292&gt; 1 == true
293true
294</pre>
295    <p>
296      To avoid type coercion, use the triple-equals operator:
297    </p>
298    <pre class="brush: js">
299&gt; 1 === true
300false
301&gt; true === true
302true
303</pre>
304    <p>
305      There are also <code>!=</code> and <code>!==</code> operato
 >rs.
306    </p>
307    <p>
308      JavaScript also has <a href="/en/JavaScript/Reference/Opera
 >tors/Bitwise_Operators" title="en/Core_JavaScript_1.5_Reference/O
 >perators/Bitwise_Operators">bitwise operations</a>. If you want t
 >o use them, they're there.
309    </p>
310    <h2 id="Control_structures">
311      Control structures
312    </h2>
313    <p>
314      JavaScript has a similar set of control structures to other
 > languages in the C family. Conditional statements are supported 
 >by <code>if</code> and <code>else</code>; you can chain them toge
 >ther if you like:
315    </p>
316    <pre class="brush: js">
317var name = "kittens";
318if (name == "puppies") {
319  name += "!";
320} else if (name == "kittens") {
321  name += "!!";
322} else {
323  name = "!" + name;
324}
325name == "kittens!!"
326</pre>
327    <p>
328      JavaScript has <code>while</code> loops and <code>do-while<
 >/code> loops. The first is good for basic looping; the second for
 > loops where you wish to ensure that the body of the loop is exec
 >uted at least once:
329    </p>
330    <pre class="brush: js">
331while (true) {
332  // an infinite loop!
333}
334 
335var input;
336do {
337  input = get_input();
338} while (inputIsNotValid(input))
339</pre>
340    <p>
341      JavaScript's <code>for</code> loop is the same as that in C
 > and Java: it lets you provide the control information for your l
 >oop on a single line.
342    </p>
343    <pre class="brush: js">
344for (var i = 0; i &lt; 5; i++) {
345  // Will execute 5 times
346}
347</pre>
348    <p>
349      The <code>&amp;&amp;</code> and <code>||</code> operators u
 >se short-circuit logic, which means whether they will execute the
 >ir second operand is dependent on the first. This is useful for c
 >hecking for null objects before accessing their attributes:
350    </p>
351    <pre class="brush: js">
352var name = o &amp;&amp; o.getName();
353</pre>
354    <p>
355      Or for setting default values:
356    </p>
357    <pre class="brush: js">
358var name = otherName || "default";
359</pre>
360    <p>
361      JavaScript has a ternary operator for conditional expressio
 >ns:
362    </p>
363    <pre class="brush: js">
364var allowed = (age &gt; 18) ? "yes" : "no";
365</pre>
366    <p>
367      The switch statement can be used for multiple branches base
 >d on a number or string:
368    </p>
369    <pre class="brush: js">
370switch(action) {
371    case 'draw':
372        drawit();
373        break;
374    case 'eat':
375        eatit();
376        break;
377    default:
378        donothing();
379}
380</pre>
381    <p>
382      If you don't add a <code>break</code> statement, execution 
 >will "fall through" to the next level. This is very rarely what y
 >ou want — in fact it's worth specifically labelling deliberate fa
 >llthrough with a comment if you really meant it to aid debugging:
383    </p>
384    <pre class="brush: js">
385switch(a) {
386    case 1: // fallthrough
387    case 2:
388        eatit();
389        break;
390    default:
391        donothing();
392}
393</pre>
394    <p>
395      The default clause is optional. You can have expressions in
 > both the switch part and the cases if you like; comparisons take
 > place between the two using the <code>===</code> operator:
396    </p>
397    <pre class="brush: js">
398switch(1 + 3) {
399    case 2 + 2:
400        yay();
401        break;
402    default:
403        neverhappens();
404}
405</pre>
406    <h2 id="Objects">
407      Objects
408    </h2>
409    <p>
410      JavaScript objects are simply collections of name-value pai
 >rs. As such, they are similar to:
411    </p>
412    <ul>
413      <li>Dictionaries in Python
414      </li>
415      <li>Hashes in Perl and Ruby
416      </li>
417      <li>Hash tables in C and C++
418      </li>
419      <li>HashMaps in Java
420      </li>
421      <li>Associative arrays in PHP
422      </li>
423    </ul>
424    <p>
425      The fact that this data structure is so widely used is a te
 >stament to its versatility. Since everything (bar core types) in 
 >JavaScript is an object, any JavaScript program naturally involve
 >s a great deal of hash table lookups. It's a good thing they're s
 >o fast!
426    </p>
427    <p>
428      The "name" part is a JavaScript string, while the value can
 > be any JavaScript value — including more objects. This allows yo
 >u to build data structures of arbitrary complexity.
429    </p>
430    <p>
431      There are two basic ways to create an empty object:
432    </p>
433    <pre class="brush: js">
434var obj = new Object();
435</pre>
436    <p>
437      And:
438    </p>
439    <pre class="brush: js">
440var obj = {};
441</pre>
442    <p>
443      These are semantically equivalent; the second is called obj
 >ect literal syntax, and is more convenient. This syntax is also t
 >he core of JSON format and should be preferred at all times.
444    </p>
445    <p>
446      Once created, an object's properties can again be accessed 
 >in one of two ways:
447    </p>
448    <pre class="brush: js">
449obj.name = "Simon";
450var name = obj.name;
451</pre>
452    <p>
453      And...
454    </p>
455    <pre class="brush: js">
456obj["name"] = "Simon";
457var name = obj["name"];
458</pre>
459    <p>
460      These are also semantically equivalent. The second method h
 >as the advantage that the name of the property is provided as a s
 >tring, which means it can be calculated at run-time though using 
 >this method prevents some JavaScript engine and minifier optimiza
 >tions being applied. It can also be used to set and get propertie
 >s with names that are <a href="/en/JavaScript/Reference/Reserved_
 >Words" title="en/Core_JavaScript_1.5_Reference/Reserved_Words">re
 >served words</a>:
461    </p>
462    <pre class="brush: js">
463obj.for = "Simon"; // Syntax error, because 'for' is a reserved w
 >ord
464obj["for"] = "Simon"; // works fine
465</pre>
466    <p>
467      Object literal syntax can be used to initialise an object i
 >n its entirety:
468    </p>
469    <pre class="brush: js">
470var obj = {
471    name: "Carrot",
472    "for": "Max",
473    details: {
474        color: "orange",
475        size: 12
476    }
477}
478</pre>
479    <p>
480      Attribute access can be chained together:
481    </p>
482    <pre class="brush: js">
483&gt; obj.details.color
484orange
485&gt; obj["details"]["size"]
48612
487</pre>
488    <h2 id="Arrays">
489      Arrays
490    </h2>
491    <p>
492      Arrays in JavaScript are actually a special type of object.
 > They work very much like regular objects (numerical properties c
 >an naturally be accessed only using [] syntax) but they have one 
 >magic property called '<code>length</code>'. This is always one m
 >ore than the highest index in the array.
493    </p>
494    <p>
495      The old way of creating arrays is as follows:
496    </p>
497    <pre class="brush: js">
498&gt; var a = new Array();
499&gt; a[0] = "dog";
500&gt; a[1] = "cat";
501&gt; a[2] = "hen";
502&gt; a.length
5033
504</pre>
505    <p>
506      A more convenient notation is to use an array literal:
507    </p>
508    <pre class="brush: js">
509&gt; var a = ["dog", "cat", "hen"];
510&gt; a.length
5113
512</pre>
513    <p>
514      Leaving a trailing comma at the end of an array literal is 
 >inconsistent across browsers, so don't do it.
515    </p>
516    <p>
517      Note that <code>array.length</code> isn't necessarily the n
 >umber of items in the array. Consider the following:
518    </p>
519    <pre class="brush: js">
520&gt; var a = ["dog", "cat", "hen"];
521&gt; a[100] = "fox";
522&gt; a.length
523101
524</pre>
525    <p>
526      Remember — the length of the array is one more than the hig
 >hest index.
527    </p>
528    <p>
529      If you query a non-existent array index, you get <code>unde
 >fined</code>:
530    </p>
531    <pre class="brush: js">
532&gt; typeof a[90]
533undefined
534</pre>
535    <p>
536      If you take the above into account, you can iterate over an
 > array using the following:
537    </p>
538    <pre class="brush: js">
539for (var i = 0; i &lt; a.length; i++) {
540    // Do something with a[i]
541}
542</pre>
543    <p>
544      This is slightly inefficient as you are looking up the leng
 >th property once every loop. An improvement is this:
545    </p>
546    <pre class="brush: js">
547for (var i = 0, len = a.length; i &lt; len; i++) {
548    // Do something with a[i]
549}
550</pre>
551    <p>
552      An even nicer idiom is:
553    </p>
554    <pre class="brush: js">
555for (var i = 0, item; item = a[i++];) {
556    // Do something with item
557}
558</pre>
559    <p>
560      Here we are setting up two variables. The assignment in the
 > middle part of the <code>for</code> loop is also tested for trut
 >hfulness — if it succeeds, the loop continues. Since <code>i</cod
 >e> is incremented each time, items from the array will be assigne
 >d to item in sequential order. The loop stops when a "falsy" item
 > is found (such as <code>undefined</code>).
561    </p>
562    <p>
563      Note that this trick should only be used for arrays which y
 >ou know do not contain "falsy" values (arrays of objects or <a hr
 >ef="/en/DOM" title="en/DOM">DOM</a> nodes for example). If you ar
 >e iterating over numeric data that might include a 0 or string da
 >ta that might include the empty string you should use the <code>i
 >, len</code> idiom instead.
564    </p>
565    <p>
566      Another way to iterate is to use the <code><a href="/en/Jav
 >aScript/Reference/Statements/for...in" title="en/Core_JavaScript_
 >1.5_Reference/Statements/for...in">for...in</a></code> loop. Note
 > that if someone added new properties to <code>Array.prototype</c
 >ode>, they will also be iterated over by this loop:
567    </p>
568    <pre class="brush: js">
569for (var i in a) {
570  // Do something with a[i]
571}
572</pre>
573    <p>
574      If you want to append an item to an array, the safest way t
 >o do it is like this:
575    </p>
576    <pre class="brush: js">
577a[a.length] = item;                 // same as a.push(item);
578</pre>
579    <p>
580      Since <code>a.length</code> is one more than the highest in
 >dex, you can be assured that you are assigning to an empty positi
 >on at the end of the array.
581    </p>
582    <p>
583      Arrays come with a number of methods:
584    </p>
585    <table height="124" width="598">
586      <thead>
587        <tr>
588          <th scope="col">
589            Method name
590          </th>
591          <th scope="col">
592            Description
593          </th>
594        </tr>
595      </thead>
596      <tbody>
597        <tr>
598          <td>
599            <code>a.toString()</code>
600          </td>
601          <td>
602            &nbsp;
603          </td>
604        </tr>
605        <tr>
606          <td>
607            <code>a.toLocaleString()</code>
608          </td>
609          <td>
610            &nbsp;
611          </td>
612        </tr>
613        <tr>
614          <td>
615            <code>a.concat(item[, itemN])</code>
616          </td>
617          <td>
618            Returns a new array with the items added on to it.
619          </td>
620        </tr>
621        <tr>
622          <td>
623            <code>a.join(sep)</code>
624          </td>
625          <td>
626            &nbsp;
627          </td>
628        </tr>
629        <tr>
630          <td>
631            <code>a.pop()</code>
632          </td>
633          <td>
634            Removes and returns the last item.
635          </td>
636        </tr>
637        <tr>
638          <td>
639            <code>a.push(item[, itemN])</code>
640          </td>
641          <td>
642            <code>Push</code> adds one or more items to the end.
643          </td>
644        </tr>
645        <tr>
646          <td>
647            <code>a.reverse()</code>
648          </td>
649          <td>
650            &nbsp;
651          </td>
652        </tr>
653        <tr>
654          <td>
655            <code>a.shift()</code>
656          </td>
657          <td>
658            &nbsp;
659          </td>
660        </tr>
661        <tr>
662          <td>
663            <code>a.slice(start, end)</code>
664          </td>
665          <td>
666            Returns a sub-array.
667          </td>
668        </tr>
669        <tr>
670          <td>
671            <code>a.sort([cmpfn])</code>
672          </td>
673          <td>
674            Takes an optional comparison function.
675          </td>
676        </tr>
677        <tr>
678          <td>
679            <code>a.splice(start, delcount[, itemN])</code>
680          </td>
681          <td>
682            Lets you modify an array by deleting a section and re
 >placing it with more items.
683          </td>
684        </tr>
685        <tr>
686          <td>
687            <code>a.unshift([item])</code>
688          </td>
689          <td>
690            Prepends items to the start of the array.
691          </td>
692        </tr>
693      </tbody>
694    </table>
695    <h2 id="Functions">
696      Functions
697    </h2>
698    <p>
699      Along with objects, functions are the core component in und
 >erstanding JavaScript. The most basic function couldn't be much s
 >impler:
700    </p>
701    <pre class="brush: js">
702function add(x, y) {
703    var total = x + y;
704    return total;
705}
706</pre>
707    <p>
708      This demonstrates everything there is to know about basic f
 >unctions. A JavaScript function can take 0 or more named paramete
 >rs. The function body can contain as many statements as you like,
 > and can declare its own variables which are local to that functi
 >on. The <code>return</code> statement can be used to return a val
 >ue at any time, terminating the function. If no return statement 
 >is used (or an empty return with no value), JavaScript returns <c
 >ode>undefined</code>.
709    </p>
710    <p>
711      The named parameters turn out to be more like guidelines th
 >an anything else. You can call a function without passing the par
 >ameters it expects, in which case they will be set to <code>undef
 >ined</code>.
712    </p>
713    <pre class="brush: js">
714&gt; add()
715NaN // You can't perform addition on undefined
716</pre>
717    <p>
718      You can also pass in more arguments than the function is ex
 >pecting:
719    </p>
720    <pre class="brush: js">
721&gt; add(2, 3, 4)
7225 // added the first two; 4 was ignored
723</pre>
724    <p>
725      That may seem a little silly, but functions have access to 
 >an additional variable inside their body called <a href="/en/Java
 >Script/Reference/Functions_and_function_scope/arguments" title="E
 >n/Core_JavaScript_1.5_Reference/Functions_and_function_scope/argu
 >ments"><code>arguments</code></a>, which is an array-like object 
 >holding all of the values passed to the function. Let's re-write 
 >the add function to take as many values as we want:
726    </p>
727    <pre class="brush: js">
728function add() {
729    var sum = 0;
730    for (var i = 0, j = arguments.length; i &lt; j; i++) {
731        sum += arguments[i];
732    }
733    return sum;
734}
735 
736&gt; add(2, 3, 4, 5)
73714
738</pre>
739    <p>
740      That's really not any more useful than writing <code>2 + 3 
 >+ 4 + 5</code> though. Let's create an averaging function:
741    </p>
742    <pre class="brush: js">
743function avg() {
744    var sum = 0;
745    for (var i = 0, j = arguments.length; i &lt; j; i++) {
746        sum += arguments[i];
747    }
748    return sum / arguments.length;
749}
750&gt; avg(2, 3, 4, 5)
7513.5
752</pre>
753    <p>
754      This is pretty useful, but introduces a new problem. The <c
 >ode>avg()</code> function takes a comma separated list of argumen
 >ts — but what if you want to find the average of an array? You co
 >uld just rewrite the function as follows:
755    </p>
756    <pre class="brush: js">
757function avgArray(arr) {
758    var sum = 0;
759    for (var i = 0, j = arr.length; i &lt; j; i++) {
760        sum += arr[i];
761    }
762    return sum / arr.length;
763}
764&gt; avgArray([2, 3, 4, 5])
7653.5
766</pre>
767    <p>
768      But it would be nice to be able to reuse the function that 
 >we've already created. Luckily, JavaScript lets you call a functi
 >on and call it with an arbitrary array of arguments, using the <a
 > href="/en/JavaScript/Reference/Global_Objects/Function/apply" ti
 >tle="en/Core_JavaScript_1.5_Reference/Global_Objects/Function/app
 >ly"><code>apply()</code></a> method of any function object.
769    </p>
770    <pre class="brush: js">
771&gt; avg.apply(null, [2, 3, 4, 5])
7723.5
773</pre>
774    <p>
775      The second argument to <code>apply()</code> is the array to
 > use as arguments; the first will be discussed later on. This emp
 >hasizes the fact that functions are objects too.
776    </p>
777    <p>
778      JavaScript lets you create anonymous functions.
779    </p>
780    <pre class="brush: js">
781var avg = function() {
782    var sum = 0;
783    for (var i = 0, j = arguments.length; i &lt; j; i++) {
784        sum += arguments[i];
785    }
786    return sum / arguments.length;
787}
788</pre>
789    <p>
790      This is semantically equivalent to the <code>function avg()
 ></code> form. It's extremely powerful, as it lets you put a full 
 >function definition anywhere that you would normally put an expre
 >ssion. This enables all sorts of clever tricks. Here's a way of "
 >hiding" some local variables — like block scope in C:
791    </p>
792    <pre class="brush: js">
793&gt; var a = 1;
794&gt; var b = 2;
795&gt; (function() {
796    var b = 3;
797    a += b;
798})();
799&gt; a
8004
801&gt; b
8022
803</pre>
804    <p>
805      JavaScript allows you to call functions recursively. This i
 >s particularly useful for dealing with tree structures, such as y
 >ou get in the browser <a href="/en/DOM" title="en/DOM">DOM</a>.
806    </p>
807    <pre class="brush: js">
808function countChars(elm) {
809    if (elm.nodeType == 3) { // TEXT_NODE
810        return elm.nodeValue.length;
811    }
812    var count = 0;
813    for (var i = 0, child; child = elm.childNodes[i]; i++) {
814        count += countChars(child);
815    }
816    return count;
817}
818</pre>
819    <p>
820      This highlights a potential problem with anonymous function
 >s: how do you call them recursively if they don't have a name? Th
 >e answer lies with the <strike><code>arguments</code> object, whi
 >ch in addition to acting as a list of arguments also provides a p
 >roperty called <code>arguments.callee</code></strike>. The <code>
 >arguments.callee</code> usage is deprecated and even disallowed i
 >n strict mode. Instead, you should use "named anonymous functions
 >" as below:
821    </p>
822    <pre class="brush: js">
823var charsInBody = (function counter(elm) {
824    if (elm.nodeType == 3) { // TEXT_NODE
825        return elm.nodeValue.length;
826    }
827    var count = 0;
828    for (var i = 0, child; child = elm.childNodes[i]; i++) {
829        count += counter(child);
830    }
831    return count;
832})(document.body);
833</pre>
834    <p>
835      The name provided to an anonymous function as above is(or a
 >t least should be) only available to the function's own scope. Th
 >is both allows more optimizations to be done by the engine and a 
 >more readable code.
836    </p>
837    <h2 id="Custom_objects">
838      Custom objects
839    </h2>
840    <div class="note">
841      <strong>Note:</strong> For a more detailed discussion of ob
 >ject-oriented programming in JavaScript, see <a href="/en/JavaScr
 >ipt/Introduction_to_Object-Oriented_JavaScript" title="https://de
 >veloper.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript
 >">Introduction to Object Oriented JavaScript</a>.
842    </div>
843    <p>
844      In classic Object Oriented Programming, objects are collect
 >ions of data and methods that operate on that data. JavaScript is
 > a prototype-based language which contains no class statement, su
 >ch as is found in C++ or Java. (This is sometimes confusing for p
 >rogrammers accustomed to languages with a class statement.) Inste
 >ad, JavaScript uses functions as classes. Let's consider a person
 > object with first and last name fields. There are two ways in wh
 >ich the name might be displayed: as "first last" or as "last, fir
 >st". Using the functions and objects that we've discussed previou
 >sly, here's one way of doing it:
845    </p>
846    <pre class="brush: js">
847function makePerson(first, last) {
848    return {
849        first: first,
850        last: last
851    }
852}
853function personFullName(person) {
854    return person.first + ' ' + person.last;
855}
856function personFullNameReversed(person) {
857    return person.last + ', ' + person.first
858}
859&gt; s = makePerson("Simon", "Willison");
860&gt; personFullName(s)
861Simon Willison
862&gt; personFullNameReversed(s)
863Willison, Simon
864</pre>
865    <p>
866      This works, but it's pretty ugly. You end up with dozens of
 > functions in your global namespace. What we really need is a way
 > to attach a function to an object. Since functions are objects, 
 >this is easy:
867    </p>
868    <pre class="brush: js">
869function makePerson(first, last) {
870    return {
871        first: first,
872        last: last,
873        fullName: function() {
874            return this.first + ' ' + this.last;
875        },
876        fullNameReversed: function() {
877            return this.last + ', ' + this.first;
878        }
879    }
880}
881&gt; s = makePerson("Simon", "Willison")
882&gt; s.fullName()
883Simon Willison
884&gt; s.fullNameReversed()
885Willison, Simon
886</pre>
887    <p>
888      There's something here we haven't seen before: the '<code><
 >a href="/en/JavaScript/Reference/Operators/this" title="en/Core_J
 >avaScript_1.5_Reference/Operators/Special_Operators/this_Operator
 >">this</a></code>' keyword. Used inside a function, '<code>this</
 >code>' refers to the current object. What that actually means is 
 >specified by the way in which you called that function. If you ca
 >lled it using <a href="/en/JavaScript/Reference/Operators/Member_
 >Operators" title="en/Core_JavaScript_1.5_Reference/Operators/Memb
 >er_Operators">dot notation or bracket notation</a> on an object, 
 >that object becomes '<code>this</code>'. If dot notation wasn't u
 >sed for the call, '<code>this</code>' refers to the global object
 >. This is a frequent cause of mistakes. For example:
889    </p>
890    <pre class="brush: js">
891&gt; s = makePerson("Simon", "Willison")
892&gt; var fullName = s.fullName;
893&gt; fullName()
894undefined undefined
895</pre>
896    <p>
897      When we call <code>fullName()</code>, '<code>this</code>' i
 >s bound to the global object. Since there are no global variables
 > called <code>first</code> or <code>last</code> we get <code>unde
 >fined</code> for each one.
898    </p>
899    <p>
900      We can take advantage of the '<code>this</code>' keyword to
 > improve our <code>makePerson</code> function:
901    </p>
902    <pre class="brush: js">
903function Person(first, last) {
904    this.first = first;
905    this.last = last;
906    this.fullName = function() {
907        return this.first + ' ' + this.last;
908    }
909    this.fullNameReversed = function() {
910        return this.last + ', ' + this.first;
911    }
912}
913var s = new Person("Simon", "Willison");
914</pre>
915    <p>
916      We've introduced another keyword: '<code><a href="/en/JavaS
 >cript/Reference/Operators/new" title="en/Core_JavaScript_1.5_Refe
 >rence/Operators/Special_Operators/new_Operator">new</a></code>'. 
 ><code>new</code> is strongly related to '<code>this</code>'. What
 > it does is it creates a brand new empty object, and then calls t
 >he function specified, with '<code>this</code>' set to that new o
 >bject. Functions that are designed to be called by '<code>new</co
 >de>' are called constructor functions. Common practise is to capi
 >talise these functions as a reminder to call them with <code>new<
 >/code>.
917    </p>
918    <p>
919      Our person objects are getting better, but there are still 
 >some ugly edges to them. Every time we create a person object we 
 >are creating two brand new function objects within it — wouldn't 
 >it be better if this code was shared?
920    </p>
921    <pre class="brush: js">
922function personFullName() {
923    return this.first + ' ' + this.last;
924}
925function personFullNameReversed() {
926    return this.last + ', ' + this.first;
927}
928function Person(first, last) {
929    this.first = first;
930    this.last = last;
931    this.fullName = personFullName;
932    this.fullNameReversed = personFullNameReversed;
933}
934</pre>
935    <p>
936      That's better: we are creating the method functions only on
 >ce, and assigning references to them inside the constructor. Can 
 >we do any better than that? The answer is yes:
937    </p>
938    <pre class="brush: js">
939function Person(first, last) {
940    this.first = first;
941    this.last = last;
942}
943Person.prototype.fullName = function() {
944    return this.first + ' ' + this.last;
945}
946Person.prototype.fullNameReversed = function() {
947    return this.last + ', ' + this.first;
948}
949</pre>
950    <p>
951      <code>Person.prototype</code> is an object shared by all in
 >stances of <code>Person</code>. It forms part of a lookup chain (
 >that has a special name, "prototype chain"): any time you attempt
 > to access a property of <code>Person</code> that isn't set, Java
 >Script will check <code>Person.prototype</code> to see if that pr
 >operty exists there instead. As a result, anything assigned to <c
 >ode>Person.prototype</code> becomes available to all instances of
 > that constructor via the <code>this</code> object.
952    </p>
953    <p>
954      This is an incredibly powerful tool. JavaScript lets you mo
 >dify something's prototype at any time in your program, which mea
 >ns you can add extra methods to existing objects at runtime:
955    </p>
956    <pre class="brush: js">
957&gt; s = new Person("Simon", "Willison");
958&gt; s.firstNameCaps();
959TypeError on line 1: s.firstNameCaps is not a function
960&gt; Person.prototype.firstNameCaps = function() {
961    return this.first.toUpperCase()
962}
963&gt; s.firstNameCaps()
964SIMON
965</pre>
966    <p>
967      Interestingly, you can also add things to the prototype of 
 >built-in JavaScript objects. Let's add a method to <code>String</
 >code> that returns that string in reverse:
968    </p>
969    <pre class="brush: js">
970&gt; var s = "Simon";
971&gt; s.reversed()
972TypeError on line 1: s.reversed is not a function
973&gt; String.prototype.reversed = function() {
974    var r = "";
975    for (var i = this.length - 1; i &gt;= 0; i--) {
976        r += this[i];
977    }
978    return r;
979}
980&gt; s.reversed()
981nomiS
982</pre>
983    <p>
984      Our new method even works on string literals!
985    </p>
986    <pre class="brush: js">
987&gt; "This can now be reversed".reversed()
988desrever eb won nac sihT
989</pre>
990    <p>
991      As I mentioned before, the prototype forms part of a chain.
 > The root of that chain is <code>Object.prototype</code>, whose m
 >ethods include <code>toString()</code>&nbsp;— it is this method t
 >hat is called when you try to represent an object as a string. Th
 >is is useful for debugging our <code>Person</code> objects:
992    </p>
993    <pre class="brush: js">
994&gt; var s = new Person("Simon", "Willison");
995&gt; s
996[object Object]
997&gt; Person.prototype.toString = function() {
998    return '&lt;Person: ' + this.fullName() + '&gt;';
999}
1000&gt; s
1001&lt;Person: Simon Willison&gt;
1002</pre>
1003    <p>
1004      Remember how <code>avg.apply()</code> had a null first argu
 >ment? We can revisit that now. The first argument to <code>apply(
 >)</code> is the object that should be treated as '<code>this</cod
 >e>'. For example, here's a trivial implementation of '<code>new</
 >code>':
1005    </p>
1006    <pre class="brush: js">
1007function trivialNew(constructor) {
1008    var o = {}; // Create an object
1009    constructor.apply(o, arguments);
1010    return o;
1011}
1012</pre>
1013    <p>
1014      This isn't an exact replica of <code>new</code> as it doesn
 >'t set up the prototype chain. <code>apply()</code> is difficult 
 >to illustrate — it's not something you use very often, but it's u
 >seful to know about.
1015    </p>
1016    <p>
1017      <code>apply()</code> has a sister function named <a href="/
 >en/JavaScript/Reference/Global_Objects/Function/call" title="en/C
 >ore_JavaScript_1.5_Reference/Global_Objects/Function/call"><code>
 >call</code></a>, which again lets you set '<code>this</code>' but
 > takes an expanded argument list as opposed to an array.
1018    </p>
1019    <pre class="brush: js">
1020function lastNameCaps() {
1021    return this.last.toUpperCase();
1022}
1023var s = new Person("Simon", "Willison");
1024lastNameCaps.call(s);
1025// Is the same as:
1026s.lastNameCaps = lastNameCaps;
1027s.lastNameCaps();
1028</pre>
1029    <h2 id="Inner_functions">
1030      Inner functions
1031    </h2>
1032    <p>
1033      JavaScript function declarations are allowed inside other f
 >unctions. We've seen this once before, with an earlier <code>make
 >Person()</code> function. An important detail of nested functions
 > in JavaScript is that they can access variables in their parent 
 >function's scope:
1034    </p>
1035    <pre class="brush: js">
1036function betterExampleNeeded() {
1037    var a = 1;
1038    function oneMoreThanA() {
1039        return a + 1;
1040    }
1041    return oneMoreThanA();
1042}
1043</pre>
1044    <p>
1045      This provides a great deal of utility in writing more maint
 >ainable code. If a function relies on one or two other functions 
 >that are not useful to any other part of your code, you can nest 
 >those utility functions inside the function that will be called f
 >rom elsewhere. This keeps the number of functions that are in the
 > global scope down, which is always a good thing.
1046    </p>
1047    <p>
1048      This is also a great counter to the lure of global variable
 >s. When writing complex code it is often tempting to use global v
 >ariables to share values between multiple functions — which leads
 > to code that is hard to maintain. Nested functions can share var
 >iables in their parent, so you can use that mechanism to couple f
 >unctions together when it makes sense without polluting your glob
 >al namespace — 'local globals' if you like. This technique should
 > be used with caution, but it's a useful ability to have.
1049    </p>
1050    <h2 id="Closures">
1051      Closures
1052    </h2>
1053    <p>
1054      This leads us to one of the most powerful abstractions that
 > JavaScript has to offer — but also the most potentially confusin
 >g. What does this do?
1055    </p>
1056    <pre class="brush: js">
1057function makeAdder(a) {
1058    return function(b) {
1059        return a + b;
1060    }
1061}
1062x = makeAdder(5);
1063y = makeAdder(20);
1064x(6)
1065?
1066y(7)
1067?
1068</pre>
1069    <p>
1070      The name of the <code>makeAdder</code> function should give
 > it away: it creates new 'adder' functions, which when called wit
 >h one argument add it to the argument that they were created with
 >.
1071    </p>
1072    <p>
1073      What's happening here is pretty much the same as was happen
 >ing with the inner functions earlier on: a function defined insid
 >e another function has access to the outer function's variables. 
 >The only difference here is that the outer function has returned,
 > and hence common sense would seem to dictate that its local vari
 >ables no longer exist. But they <em>do</em> still exist — otherwi
 >se the adder functions would be unable to work. What's more, ther
 >e are two different "copies" of <code>makeAdder</code>'s local va
 >riables — one in which <code>a</code> is 5 and one in which <code
 >>a</code> is 20. So the result of those function calls is as foll
 >ows:
1074    </p>
1075    <pre class="brush: js">
1076x(6) // returns 11
1077y(7) // returns 27
1078</pre>
1079    <p>
1080      Here's what's actually happening. Whenever JavaScript execu
 >tes a function, a 'scope' object is created to hold the local var
 >iables created within that function. It is initialised with any v
 >ariables passed in as function parameters. This is similar to the
 > global object that all global variables and functions live in, b
 >ut with a couple of important differences: firstly, a brand new s
 >cope object is created every time a function starts executing, an
 >d secondly, unlike the global object (which in browsers is access
 >ible as window) these scope objects cannot be directly accessed f
 >rom your JavaScript code. There is no mechanism for iterating ove
 >r the properties of the current scope object for example.
1081    </p>
1082    <p>
1083      So when <code>makeAdder</code> is called, a scope object is
 > created with one property: <code>a</code>, which is the argument
 > passed to the <code>makeAdder</code> function. <code>makeAdder</
 >code> then returns a newly created function. Normally JavaScript'
 >s garbage collector would clean up the scope object created for <
 >code>makeAdder</code> at this point, but the returned function ma
 >intains a reference back to that scope object. As a result, the s
 >cope object will not be garbage collected until there are no more
 > references to the function object that <code>makeAdder</code> re
 >turned.
1084    </p>
1085    <p>
1086      Scope objects form a chain called the scope chain, similar 
 >to the prototype chain used by JavaScript's object system.
1087    </p>
1088    <p>
1089      A closure is the combination of a function and the scope ob
 >ject in which it was created.
1090    </p>
1091    <p>
1092      Closures let you save state — as such, they can often be us
 >ed in place of objects.
1093    </p>
1094    <h3 id="Memory_leaks">
1095      Memory leaks
t23      Returns the string&nbsp;<code style="font-size: 14px;">"foot1098      An unfortunate side effect of closures is that they make it
>"</code>.> trivially easy to leak memory in Internet Explorer. JavaScript i
 >s a garbage collected language — objects are allocated memory upo
 >n their creation and that memory is reclaimed by the browser when
 > no references to an object remain. Objects provided by the host 
 >environment are handled by that environment.
24    </p>
25    <h3 id="Preference_APIs">
26      Preference APIs
27    </h3>
28    <p>1099    </p>
29      See {{ interface("nsIPrefBranch") }} for documentation on t
>he APIs that these methods use internally. 
30    </p>1100    <p>
31    <h4 id="SpecialPowers.getBoolPref(aPrefName)">1101      Browser hosts need to manage a large number of objects repr
 >esenting the HTML page being presented — the objects of the <a hr
 >ef="/en/DOM" title="en/DOM">DOM</a>. It is up to the browser to m
 >anage the allocation and recovery of these.
32      SpecialPowers.getBoolPref(aPrefName)
33    </h4>
34    <p>1102    </p>
35      Get the value of the preference&nbsp;<code style="font-size
>: 14px;">aPrefName</code>&nbsp;as a boolean. 
36    </p>1103    <p>
37    <h4 id="SpecialPowers.getIntPref(aPrefName)">1104      Internet Explorer uses its own garbage collection scheme fo
 >r this, separate from the mechanism used by JavaScript. It is the
 > interaction between the two that can cause memory leaks.
38      SpecialPowers.getIntPref(aPrefName)
39    </h4>
40    <p>1105    </p>
41      Get the value of the preference&nbsp;<code style="font-size
>: 14px;">aPrefName</code>&nbsp;as an integer. 
42    </p>1106    <p>
43    <h4 id="SpecialPowers.getCharPref(aPrefName)">1107      A memory leak in IE occurs any time a circular reference is
 > formed between a JavaScript object and a native object. Consider
 > the following:
44      SpecialPowers.getCharPref(aPrefName)
45    </h4>
46    <p>1108    </p>
47      Get the value of the preference&nbsp;<code style="font-size1109    <pre class="brush: js">
>: 14px;">aPrefName</code>&nbsp;as a string. 
1110function leakMemory() {
1111    var el = document.getElementById('el');
1112    var o = { 'el': el };
1113    el.o = o;
1114}
1115</pre>
48    </p>1116    <p>
49    <h4 id="SpecialPowers.getComplexValue(aPrefName)">1117      The circular reference formed above creates a memory leak; 
 >IE will not free the memory used by <code>el</code> and <code>o</
 >code> until the browser is completely restarted.
50      SpecialPowers.getComplexValue(aPrefName)
51    </h4>
52    <p>1118    </p>
53      Get the value of the preference&nbsp;<code style="font-size
>: 14px;">aPrefName</code>&nbsp;as an XPCOM&nbsp;object. 
54    </p>1119    <p>
55    <h4 id="SpecialPowers.setBoolPref(aPrefName.2C_aValue)">1120      The above case is likely to go unnoticed; memory leaks only
 > become a real concern in long running applications or applicatio
 >ns that leak large amounts of memory due to large data structures
 > or leak patterns within loops.
56      SpecialPowers.setBoolPref(aPrefName, aValue)
57    </h4>
58    <p>1121    </p>
59      Set the value of the preference&nbsp;<code style="font-size
>: 14px;">aPrefName</code>&nbsp;to the boolean value&nbsp;<code st 
>yle="font-size: 14px;">aValue</code>. 
60    </p>1122    <p>
61    <h4 id="SpecialPowers.setIntPref(aPrefName.2C_aValue)">1123      Leaks are rarely this obvious — often the leaked data struc
 >ture can have many layers of references, obscuring the circular r
 >eference.
62      SpecialPowers.setIntPref(aPrefName, aValue)
63    </h4>
64    <p>1124    </p>
65      Set the value of the preference&nbsp;<code style="font-size
>: 14px;">aPrefName</code>&nbsp;to the integer value&nbsp;<code st 
>yle="font-size: 14px;">aValue</code>. 
66    </p>1125    <p>
67    <h4 id="SpecialPowers.setCharPref(aPrefName.2C_aValue)">1126      Closures make it easy to create a memory leak without meani
 >ng to. Consider this:
68      SpecialPowers.setCharPref(aPrefName, aValue)
69    </h4>
70    <p>1127    </p>
71      Set the value of the preference&nbsp;<code style="font-size1128    <pre class="brush: js">
>: 14px;">aPrefName</code>&nbsp;to the string value&nbsp;<code sty 
>le="font-size: 14px;">aValue</code>. 
1129function addHandler() {
1130    var el = document.getElementById('el');
1131    el.onclick = function() {
1132        this.style.backgroundColor = 'red';
1133    }
1134}
1135</pre>
72    </p>1136    <p>
73    <h4 id="SpecialPowers.setComplexValue(aPrefName.2C_aValue)">1137      The above code sets up the element to turn red when it is c
 >licked. It also creates a memory leak. Why? Because the reference
 > to <code>el</code> is inadvertently caught in the closure create
 >d for the anonymous inner function. This creates a circular refer
 >ence between a JavaScript object (the function) and a native obje
 >ct (<code>el</code>).
74      SpecialPowers.setComplexValue(aPrefName, aValue)
75    </h4>
76    <p>1138    </p>
77      Set the value of the preference&nbsp;<code style="font-size1139    <pre class="script" style="font-size: 16px;">
>: 14px;">aPrefName</code>&nbsp;to the XPCOM&nbsp;object&nbsp;<cod 
>e style="font-size: 14px;">aValue</code>. 
1140needsTechnicalReview();
1141</pre>
78    </p>1142    <p>
79    <h4 id="SpecialPowers.clearUserPref(aPrefName)">1143      There are a number of workarounds for this problem. The sim
 >plest is not to use the <code>el</code> variable:
80      SpecialPowers.clearUserPref(aPrefName)
81    </h4>
82    <p>1144    </p>
83      Reset the preference&nbsp;<code style="font-size: 14px;">aP1145    <pre class="brush: js">
>refName&nbsp;</code>to its default value. 
1146function addHandler(){
1147    document.getElementById('el').onclick = function(){
1148        this.style.backgroundColor = 'red';
1149    }
1150}
1151</pre>
84    </p>1152    <p>
85    <h3 id="Event_Listener_APIs">1153      Surprisingly, one trick for breaking circular references in
 >troduced by a closure is to add another closure:
86      Event Listener APIs
87    </h3>
88    <h4 id="SpecialPowers.addChromeEventListener(type.2C_listener
>.2C_capture.2C_allowUntrusted)"> 
89      SpecialPowers.addChromeEventListener(type, listener, captur
>e, allowUntrusted) 
90    </h4>
91    <p>1154    </p>
92      Adds an event listener to the TabChildGlobal object.1155    <pre class="brush: js">
1156function addHandler() {
1157    var clickHandler = function() {
1158        this.style.backgroundColor = 'red';
1159    };
1160    (function() {
1161        var el = document.getElementById('el');
1162        el.onclick = clickHandler;
1163    })();
1164}
1165</pre>
93    </p>1166    <p>
94    <h4 id="SpecialPowers.removeChromeEventListener(type.2C_liste1167      The inner function is executed straight away, and hides its
>ner.2C_capture)">> contents from the closure created with <code>clickHandler</code>
 >.
95      SpecialPowers.removeChromeEventListener(type, listener, cap
>ture) 
96    </h4>
97    <p>1168    </p>
98      Removes an event listener from the TabChildGlobal object.
99    </p>1169    <p>
100    <h3 id="Other_APIs">1170      Another good trick for avoiding closures is breaking circul
 >ar references during the <code>window.onunload</code> event. Many
 > event libraries will do this for you. Note that doing so disable
 >s <a href="/En/Using_Firefox_1.5_caching" title="En/Using_Firefox
 >_1.5_caching">bfcache in Firefox 1.5</a>, so you should not regis
 >ter an <code>unload</code> listener in Firefox, unless you have o
 >ther reasons to do so.
101      Other APIs
102    </h3>
103    <h4 id="SpecialPowers.createSystemXHR()">
104      SpecialPowers.createSystemXHR()
105    </h4>
106    <p>1171    </p>
107      Creates and returns a XMLHttpRequest instance which has ful1172    <div class="originaldocinfo">
>l "system privileges". In other words, it can: 
108    </p>1173      <h2 id="Original_Document_Information" name="Original_Docum
 >ent_Information">
1174        Original Document Information
1175      </h2>
109    <ul>1176      <ul>
110      <li>Make cross-site requests without any restrictions. I.e.1177        <li>Author: <a class="external" href="http://simon.incuti
> the target server does not need to support CORS.>o.com/">Simon Willison</a>
111      </li>1178        </li>
112      <li>Set any header using xhr.setRequestHeader.1179        <li>Last Updated Date: March 7, 2006
113      </li>1180        </li>
114      <li>Read any response using xhr.getResponseHeader and xhr.g1181        <li>Copyright: © 2006 Simon Willison, contributed under t
>etAllResponseHeaders.>he Creative Commons: Attribute-Sharealike 2.0 license.
115      </li>1182        </li>
116      <li>Load and parse XUL&nbsp;contents using the xhr.response1183        <li>More information: For more information about this tut
>XML&nbsp;property.>orial (and for links to the original talk's slides), see Simon's 
 ><a class="external" href="http://simon.incutio.com/archive/2006/0
 >3/07/etech">Etech weblog post</a>.
117      </li>1184        </li>
118      <li>Make requests without a&nbsp;<code style="font-size: 14
>px;">referer</code>&nbsp;(sic) header. If you want a&nbsp;<code s 
>tyle="font-size: 14px;">referer</code>&nbsp;header set, you have  
>to do so manually using xhr.setRequestHeader. 
119      </li>1185      </ul>
120    </ul>
121    <p>
122      However, any document parsed by the xhr object and accessed
> through xhr.responseXML is created using a null principal and wh 
>ich limits what the document can do. 
123    </p>
124    <h4 id="SpecialPowers.gc()">
125      SpecialPowers.gc()
126    </h4>
127    <p>
128      Forces a round of garbage collection to be performed.
129    </p>
130    <h4 id="SpecialPowers.MockFilePicker">
131      SpecialPowers.MockFilePicker
132    </h4>
133    <p>
134      After the completion of&nbsp;<a class="link-https" href="ht
>tps://bugzilla.mozilla.org/show_bug.cgi?id=668154"><strong>Bug&nb 
>sp;668154</strong></a>, MockFilePicker will be available in Speci 
>alPowers. This replaces the standard File Picker with one that ca 
>n be controlled via script, for testing load and save code. To us 
>e it, add the following lines of code to your test: 
135    </p>
136    <pre class="brush: js" style="font-size: 14px;">
137var MockFilePicker = SpecialPowers.MockFilePicker;
138MockFilePicker.reset(); // You must call reset before each test
139</pre>
140    <p>
141      <a class="link-https" href="https://bugzilla.mozilla.org/at
>tachment.cgi?id=544963&amp;action=diff" title="https://bugzilla.m 
>ozilla.org/attachment.cgi?id=544963&amp;action=diff">This patch</ 
>a>&nbsp;has examples of how to use the MockFilePicker, and also h 
>ow to use it for XPCShell tests. The code in&nbsp;<code style="fo 
>nt-size: 14px;">testing/mochitest/MockFilePicker.jsm</code>&nbsp; 
>might also be helpful. 
142    </p>
143    <h2 id="Adding_new_APIs">
144      Adding new APIs
145    </h2>
146    <p>
147      If your test requires privileged functionality that's not c
>urrently present, you can add new APIs to the SpecialPowers objec 
>t. 
148    </p>
149    <div class="note">
150      The SpecialPowers APIs are designed to be forwards-compatib
>le with the Electrolysis project, so that they work when content  
>is run in a separate process (such as in Firefox Mobile). Any cha 
>nges you make must take this into account, or they will not be ac 
>cepted. 
151    </div>
152    <p>
153      Because of the support for out-of-process content, the Spec
>ialPowers implementation is split into two separate files: 
154    </p>
155    <ul>
156      <li>{{ Source("testing/mochitest/specialpowers/components/S
>pecialPowersObserver.js", "SpecialPowersObserver.js") }}, which i 
>s always run in the parent process. 
157      </li>
158      <li>{{ Source("testing/mochitest/specialpowers/content/spec
>ialpowers.js", "specialpowers.js") }}, which is a&nbsp;<a href="/ 
>en/The_message_manager#The_content_script" title="en/The message  
>manager#The content script">content script</a>, and may be run in 
> the content process. 
159      </li>
160    </ul>
161    <p>
162      Both files execute with chrome privileges, but certain XPCO
>M&nbsp;APIs are not available in content processes. Consult with  
>an Electrolysis or Mobile peer if you are unsure if you can use a 
> specific API there. You may also want to read the&nbsp;<a href=" 
>/en/The_message_manager" title="en/The message manager">Message M 
>anager</a>&nbsp;documentation for more detailed information on ho 
>w cross-process messaging works. 
163    </p>
164    <h3 id="A_simple_example">
165      A simple example
166    </h3>
167    <p>
168      Let's say you wanted to expose the&nbsp;<code style="font-s
>ize: 14px;">numberOfScreens</code>&nbsp;attribute from the {{ int 
>erface("nsIScreenManager") }} interface. Let's also suppose that  
>this interface is not available in the content process, just to m 
>ake our example more complete. To start, first you would need to  
>define the new API on the&nbsp;<code style="font-size: 14px;">Spe 
>cialPowers</code>&nbsp;object that is exposed to content. This ob 
>ject is defined in {{ Source("testing/mochitest/specialpowers/con 
>tent/specialpowers.js", "the content script") }}. 
169    </p>
170    <div class="note">
171      Since&nbsp;<code style="font-size: 14px;">SpecialPowers</co
>de>&nbsp;is just a normal JavaScript object, you can add function 
>s, attributes, getters and setters to it like any other object. I 
>t does use the special<span id="the-code">&nbsp;<code style="font 
>-size: 14px;">__exposedProps__</code>&nbsp;property to hide any p 
>roperty beginning with an underscore ("_") from content scripts,  
>so names starting with an underscore function like private member 
>s.</span> 
172    </div>
173    <p>
174      Let's first add a&nbsp;<code style="font-size: 14px;">numbe
>rOfScreens</code>&nbsp;getter to&nbsp;<code style="font-size: 14p 
>x;">SpecialPowers</code>. It will simply send a blocking message  
>to the chrome process, asking it to return the value in its respo 
>nse: 
175    </p>
176    <pre lang="en" style="font-size: 14px;">
177<span id="the-code"><span class="v">var </span><a class="d" href=
>"http://mxr.mozilla.org/mozilla-central/ident?i=SpecialPowers">Sp 
>ecialPowers</a> = { 
178  // existing APIs
179  //...
180 
181</span><span id="the-code">  // Provide nsIScreenManager.numberOf
>Screens 
182  get numberOfScreens() {
183    // You could pass additional parameters in the second paramet
>er, consult the <a href="mks://localhost/en/The_message_manager"  
>title="en/The message manager">message manager</a> documentation  
>for more details. 
184    // Ideally this would be a memoizing getter, that's somewhat 
>out of scope for this document. 
185    return sendSyncMessage("SPNumberOfScreens", {})[0];
186  }</span>
187<span id="the-code">};
188</span>
189</pre>
190    <p>
191      Now you need to provide a handler for this message in the {
>{ Source("testing/mochitest/specialpowers/components/SpecialPower 
>sObserver.js", "chrome observer script") }}. In the&nbsp;<span id 
>="the-code"><code style="font-size: 14px;">SpecialPowersObserver. 
>observe</code>&nbsp;function, register your message underneath th 
>e existing messages:</span> 
192    </p>
193    <pre lang="en" style="font-size: 14px;">
194<span id="the-code">// Register for any messages our API needs us
> to handle 
195</span><span id="the-code"><a class="d" href="http://mxr.mozilla.
>org/mozilla-central/ident?i=messageManager">messageManager</a>.<a 
> class="d" href="http://mxr.mozilla.org/mozilla-central/ident?i=a 
>ddMessageListener">addMessageListener</a>(<span class="s">"SPPref 
>Service"</span>, <span class="v">this)</span>; 
196</span><span id="the-code"><a class="d" href="http://mxr.mozilla.
>org/mozilla-central/ident?i=messageManager">messageManager</a>.<a 
> class="d" href="http://mxr.mozilla.org/mozilla-central/ident?i=a 
>ddMessageListener">addMessageListener</a>(<span class="s">"SPNumb 
>erOfScreens"</span>, <span class="v">this)</span>;</span> 
197</pre>
198    <p>
199      Then, in the&nbsp;<code style="font-size: 14px;"><span id="
>the-code">SpecialPowersObserver.receiveMessage</span></code>&nbsp 
>;function, add a branch to handle your new message and return the 
> result: 
200    </p>
201    <pre lang="en" style="font-size: 14px;">
202<span id="the-code">receiveMessage: <span class="v">function(</sp
>an>aMessage) { 
203</span><span id="the-code"><span class="v">  switch(aMessage.name
>) </span>{ 
204    <span class="v">case </span><span class="s">"SPPrefService"</
>span>:</span> 
205    // existing code...
206 
207    case "SPNumberOfScreens":
208      var screenManager = Components.classes["@mozilla.org/gfx/sc
>reenmanager;1"] 
209                    .getService(Components.interfaces.nsIScreenMa
>nager);<span id="the-code">} 
210      return screenManager.numberOfScreens;
211 
212    default:
213</span>
214</pre>
215    <p>
216      That's it! You will need to rebuild in the testing/mochites
>t directory in your object directory for your changes to show up, 
> then you should be able to use your new&nbsp;<code style="font-s 
>ize: 14px;">SpecialPowers.numberOfScreens</code>&nbsp;property in 
> Mochitests. 
217    </p>
218    <div class="note">
219      Don't forget to document your new API on this page after yo
>u land it! 

Back to History