Compare Revisions

A re-introduction to JavaScript (JS tutorial)

Change Revisions

Revision 295070:

Revision 295070 by berkerpeksag on

Revision 345153:

Revision 345153 by ozzydevil on

Title:
A re-introduction to JavaScript (JS Tutorial)
SpecialPowers
Slug:
JavaScript/A_re-introduction_to_JavaScript
JavaScript/A_re-introduction_to_JavaScript
Content:

Revision 295070
Revision 345153
n7    <h2 id="Introduction">n7    <p>
8      Introduction8      &nbsp;
9    </p>
10    <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    <div class="note">
14      If your Mochitest needs to perform a wide range of privileg
 >ed actions, it should probably be a&nbsp;<a href="/en/Chrome_test
 >s" title="en/Chrome tests">Chrome Mochitest</a>&nbsp;instead.
15    </div>
16    <h2 id="Existing_APIs">
17      Existing APIs
nn19    <h3 id="SpecialPowers.sanityCheck()">
20      SpecialPowers.sanityCheck()
10    <p>21    </h3>
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. 
12    </p>22    <p>
23      Returns the string&nbsp;<code style="font-size: 14px;">"foo
 >"</code>.
13    <p>24    </p>
14      It's useful to start with an idea of the language's history25    <h3 id="Preference_APIs">
>. 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. 
26      Preference APIs
27    </h3>
15    </p>28    <p>
29      See {{ interface("nsIPrefBranch") }} for documentation on t
 >he APIs that these methods use internally.
16    <p>30    </p>
17      Microsoft released a mostly-compatible version of the langu31    <h4 id="SpecialPowers.getBoolPref(aPrefName)">
>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. 
32      SpecialPowers.getBoolPref(aPrefName)
33    </h4>
18    </p>34    <p>
35      Get the value of the preference&nbsp;<code style="font-size
 >: 14px;">aPrefName</code>&nbsp;as a boolean.
19    <p>36    </p>
20      This stability is great news for developers, as it's given 37    <h4 id="SpecialPowers.getIntPref(aPrefName)">
>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. 
38      SpecialPowers.getIntPref(aPrefName)
39    </h4>
21    </p>40    <p>
41      Get the value of the preference&nbsp;<code style="font-size
 >: 14px;">aPrefName</code>&nbsp;as an integer.
22    <p>42    </p>
23      Unlike most programming languages, the JavaScript language 43    <h4 id="SpecialPowers.getCharPref(aPrefName)">
>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. 
44      SpecialPowers.getCharPref(aPrefName)
45    </h4>
24    </p>46    <p>
25    <h2 id="Overview">47      Get the value of the preference&nbsp;<code style="font-size
 >: 14px;">aPrefName</code>&nbsp;as a string.
26      Overview48    </p>
49    <h4 id="SpecialPowers.getComplexValue(aPrefName)">
50      SpecialPowers.getComplexValue(aPrefName)
51    </h4>
52    <p>
53      Get the value of the preference&nbsp;<code style="font-size
 >: 14px;">aPrefName</code>&nbsp;as an XPCOM&nbsp;object.
54    </p>
55    <h4 id="SpecialPowers.setBoolPref(aPrefName.2C_aValue)">
56      SpecialPowers.setBoolPref(aPrefName, aValue)
57    </h4>
58    <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>
61    <h4 id="SpecialPowers.setIntPref(aPrefName.2C_aValue)">
62      SpecialPowers.setIntPref(aPrefName, aValue)
63    </h4>
64    <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>
67    <h4 id="SpecialPowers.setCharPref(aPrefName.2C_aValue)">
68      SpecialPowers.setCharPref(aPrefName, aValue)
69    </h4>
70    <p>
71      Set the value of the preference&nbsp;<code style="font-size
 >: 14px;">aPrefName</code>&nbsp;to the string value&nbsp;<code sty
 >le="font-size: 14px;">aValue</code>.
72    </p>
73    <h4 id="SpecialPowers.setComplexValue(aPrefName.2C_aValue)">
74      SpecialPowers.setComplexValue(aPrefName, aValue)
75    </h4>
76    <p>
77      Set the value of the preference&nbsp;<code style="font-size
 >: 14px;">aPrefName</code>&nbsp;to the XPCOM&nbsp;object&nbsp;<cod
 >e style="font-size: 14px;">aValue</code>.
78    </p>
79    <h4 id="SpecialPowers.clearUserPref(aPrefName)">
80      SpecialPowers.clearUserPref(aPrefName)
81    </h4>
82    <p>
83      Reset the preference&nbsp;<code style="font-size: 14px;">aP
 >refName&nbsp;</code>to its default value.
84    </p>
85    <h3 id="Event_Listener_APIs">
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>
92      Adds an event listener to the TabChildGlobal object.
93    </p>
94    <h4 id="SpecialPowers.removeChromeEventListener(type.2C_liste
 >ner.2C_capture)">
95      SpecialPowers.removeChromeEventListener(type, listener, cap
 >ture)
96    </h4>
97    <p>
98      Removes an event listener from the TabChildGlobal object.
99    </p>
100    <h3 id="Other_APIs">
101      Other APIs
102    </h3>
103    <h4 id="SpecialPowers.createSystemXHR()">
104      SpecialPowers.createSystemXHR()
105    </h4>
106    <p>
107      Creates and returns a XMLHttpRequest instance which has ful
 >l "system privileges". In other words, it can:
108    </p>
109    <ul>
110      <li>Make cross-site requests without any restrictions. I.e.
 > the target server does not need to support CORS.
111      </li>
112      <li>Set any header using xhr.setRequestHeader.
113      </li>
114      <li>Read any response using xhr.getResponseHeader and xhr.g
 >etAllResponseHeaders.
115      </li>
116      <li>Load and parse XUL&nbsp;contents using the xhr.response
 >XML&nbsp;property.
117      </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>
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
n29      JavaScript is an object oriented dynamic language; it has tn147      If your test requires privileged functionality that's not c
>ypes and operators, core objects, and methods. Its syntax comes f>urrently present, you can add new APIs to the SpecialPowers objec
>rom the Java and C languages, so many structures from those langu>t.
>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>148    </p>
32      Let's start off by looking at the building block of any lan149    <div class="note">
>guage: the types. JavaScript programs manipulate values, and thos 
>e values all belong to a type. JavaScript's types are: 
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:
nn156      <li>{{ Source("testing/mochitest/specialpowers/components/S
 >pecialPowersObserver.js", "SpecialPowersObserver.js") }}, which i
 >s always run in the parent process.
35      <li>157      </li>
36        <a href="/En/Core_JavaScript_1.5_Reference/Global_Objects158      <li>{{ Source("testing/mochitest/specialpowers/content/spec
>/Number" title="en/Core_JavaScript_1.5_Reference/Global_Objects/N>ialpowers.js", "specialpowers.js") }}, which is a&nbsp;<a href="/
>umber">Numbers</a>>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.
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> 
n52      ... oh, and Undefined and Null, which are slightly odd. Andn162      Both files execute with chrome privileges, but certain XPCO
> <a href="/en/JavaScript/Reference/Global_Objects/Array" title="e>M&nbsp;APIs are not available in content processes. Consult with 
>n/Core_JavaScript_1.5_Reference/Global_Objects/Array">Arrays</a>,>an Electrolysis or Mobile peer if you are unsure if you can use a
> which are a special kind of object. And <a href="/en/JavaScript/> specific API there. You may also want to read the&nbsp;<a href="
>Reference/Global_Objects/Date" title="en/Core_JavaScript_1.5_Refe>/en/The_message_manager" title="en/The message manager">Message M
>rence/Global_Objects/Date">Dates</a> and <a href="/en/JavaScript/>anager</a>&nbsp;documentation for more detailed information on ho
>Reference/Global_Objects/RegExp" title="en/Core_JavaScript_1.5_Re>w cross-process messaging works.
>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>163    </p>
79      And there are some built in <a href="/en/JavaScript/Referen164    <h3 id="A_simple_example">
>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. 
165      A simple example
166    </h3>
80    </p>167    <p>
81    <h2 id="Numbers">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") }}.
82      Numbers
83    </h2>
84    <p>169    </p>
85      Numbers in JavaScript are "double-precision 64-bit format I170    <div class="note">
>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: 
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>
86    </p>173    <p>
87    <pre class="eval">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:
880.1 + 0.2 == 0.30000000000000004
89</pre>
90    <p>175    </p>
91      In practice, integer values are treated as 32-bit ints (and176    <pre lang="en" style="font-size: 14px;">
> 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>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> = {
93    <p>178  // existing APIs
94      The standard <a href="/en/JavaScript/Reference/Operators/Ar179  //...
>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>
177    <div class="note">
178      <strong>Note:</strong> The <a href="/en/JavaScript/Referenc
>e/Global_Objects/parseInt" title="en/JavaScript/Reference/Global  
>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. 
179    </div>
180    <h2 id="Strings">
181      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. 
185    </p>
186    <p>
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}
n335var input;n181</span><span id="the-code">  // Provide nsIScreenManager.numberOf
 >Screens
336do {182  get numberOfScreens() {
337  input = get_input();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.
338} while (inputIsNotValid(input))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>
n340    <p>n
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>190    <p>
343    <pre class="brush: js">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>
344for (var i = 0; i &lt; 5; i++) {
345  // Will execute 5 times
346}
347</pre>
348    <p>192    </p>
349      The <code>&amp;&amp;</code> and <code>||</code> operators u193    <pre lang="en" style="font-size: 14px;">
>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: 
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>
350    </p>198    <p>
351    <pre class="brush: js">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:
352var name = o &amp;&amp; o.getName();
353</pre>
354    <p>200    </p>
355      Or for setting default values:201    <pre lang="en" style="font-size: 14px;">
356    </p>202<span id="the-code">receiveMessage: <span class="v">function(</sp
 >an>aMessage) {
357    <pre class="brush: js">203</span><span id="the-code"><span class="v">  switch(aMessage.name
 >) </span>{
358var name = otherName || "default";204    <span class="v">case </span><span class="s">"SPPrefService"</
 >span>:</span>
359</pre>205    // existing code...
360    <p>206 
361      JavaScript has a ternary operator for conditional expressio207    case "SPNumberOfScreens":
>ns: 
362    </p>208      var screenManager = Components.classes["@mozilla.org/gfx/sc
 >reenmanager;1"]
363    <pre class="brush: js">209                    .getService(Components.interfaces.nsIScreenMa
 >nager);<span id="the-code">}
364var allowed = (age &gt; 18) ? "yes" : "no";210      return screenManager.numberOfScreens;
365</pre>211 
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;
n378        donothing();n213</span>
379}
n381    <p>n
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>215    <p>
384    <pre class="brush: js">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.
385switch(a) {
386    case 1: // fallthrough
387    case 2:
388        eatit();
389        break;
390    default:
391        donothing();
392}
393</pre>
394    <p>217    </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>
t841      <strong>Note:</strong> For a more detailed discussion of obt219      Don't forget to document your new API on this page after yo
>ject-oriented programming in JavaScript, see <a href="/en/JavaScr>u land it!
>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
1096    </h3>
1097    <p>
1098      An unfortunate side effect of closures is that they make it
> 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. 
1099    </p>
1100    <p>
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. 
1102    </p>
1103    <p>
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. 
1105    </p>
1106    <p>
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: 
1108    </p>
1109    <pre class="brush: js">
1110function leakMemory() {
1111    var el = document.getElementById('el');
1112    var o = { 'el': el };
1113    el.o = o;
1114}
1115</pre>
1116    <p>
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. 
1118    </p>
1119    <p>
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. 
1121    </p>
1122    <p>
1123      Leaks are rarely this obvious — often the leaked data struc
>ture can have many layers of references, obscuring the circular r 
>eference. 
1124    </p>
1125    <p>
1126      Closures make it easy to create a memory leak without meani
>ng to. Consider this: 
1127    </p>
1128    <pre class="brush: js">
1129function addHandler() {
1130    var el = document.getElementById('el');
1131    el.onclick = function() {
1132        this.style.backgroundColor = 'red';
1133    }
1134}
1135</pre>
1136    <p>
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>). 
1138    </p>
1139    <pre class="script" style="font-size: 16px;">
1140needsTechnicalReview();
1141</pre>
1142    <p>
1143      There are a number of workarounds for this problem. The sim
>plest is not to use the <code>el</code> variable: 
1144    </p>
1145    <pre class="brush: js">
1146function addHandler(){
1147    document.getElementById('el').onclick = function(){
1148        this.style.backgroundColor = 'red';
1149    }
1150}
1151</pre>
1152    <p>
1153      Surprisingly, one trick for breaking circular references in
>troduced by a closure is to add another closure: 
1154    </p>
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>
1166    <p>
1167      The inner function is executed straight away, and hides its
> contents from the closure created with <code>clickHandler</code> 
>. 
1168    </p>
1169    <p>
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. 
1171    </p>
1172    <div class="originaldocinfo">
1173      <h2 id="Original_Document_Information" name="Original_Docum
>ent_Information"> 
1174        Original Document Information
1175      </h2>
1176      <ul>
1177        <li>Author: <a class="external" href="http://simon.incuti
>o.com/">Simon Willison</a> 
1178        </li>
1179        <li>Last Updated Date: March 7, 2006
1180        </li>
1181        <li>Copyright: © 2006 Simon Willison, contributed under t
>he Creative Commons: Attribute-Sharealike 2.0 license. 
1182        </li>
1183        <li>More information: For more information about this tut
>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>. 
1184        </li>
1185      </ul>

Back to History