Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 768 lines (724 sloc) 41.607 kb
ca120a73 »
2010-11-12 first commit
1 <html>
2 <head>
3 <title>JSLint: The JavaScript Code Quality Tool</title>
4 <link rel="icon" type="image/gif" href="http://www.JSLint.com/favicon.gif">
5 <style>
6 body {
7 background-color: linen;
8 margin-left: 8%;
9 margin-right: 8%;
10 }
1ebebf33 »
2011-07-19 cleanup
11 pre {
12 margin-left: 40px;
13 }
14 table {
15 margin: 10px;
16 border: 0px;
17 }
18 th, td {
19 border: black solid 1pt;
20 padding-left: 10px;
21 padding-right: 10px;
22 vertical-align: top;
23 }
ca120a73 »
2010-11-12 first commit
24 th {
25 background-color: thistle;
26 }
27 td {
28 background-color: white;
29 }
1ebebf33 »
2011-07-19 cleanup
30 #top table {
31 margin: 0px;
32 }
33 #top td {
34 background-color: linen;
35 border: 0pt;
36 vertical-align: middle;
37 }
38 ul {
39 list-style-type: square;
40 }
41 input[type="button"] {
42 border: 2px solid black;
43 }
44 a:link {
45 color: darkblue;
46 }
47 a:visited {
48 color: purple;
49 }
50 a:hover {
51 color: blue;
52 text-decoration: underline;
53 }
54 a:active {color: red;
55 }
ca120a73 »
2010-11-12 first commit
56 </style>
57 </head>
58 <body bgcolor="gainsboro">
59 <table id="top" border="0">
60 <tr>
61 <td><img src="jslint.gif" width="383" height="120" alt="JSLint"> </td>
62 <td>
63 <p><big><code>JSLint</code>: The
64 <a href="http://javascript.crockford.com/">JavaScript</a> Code Quality Tool</big></p>
65 <p><a href="http://www.crockford.com/" target="_top">&copy;2002 Douglas Crockford</a></p>
66 </td>
67 </tr>
68 </table>
69 <br clear="all">
70 <h2 id=warning>Warning!</h2>
71 <p><a href="http://www.JSLint.com" target="_blank"><code>JSLint</code></a>
72 will hurt your feelings.</p>
73 <h2 id=what>What is <code>JSLint</code>?</h2>
74
75 <p><a href="http://www.JSLint.com" target="_blank"><code>JSLint</code></a>
76 is a JavaScript program that looks for problems in JavaScript programs.
77 It is a code quality tool.</p>
78
79 <p>When <a href="http://en.wikipedia.org/wiki/C_programming_language">C</a>
80 was a <a href="http://cm.bell-labs.com/cm/cs/who/dmr/chist.html">young</a>
81 programming language, there were several common programming errors that
82 were not caught by the primitive compilers, so an accessory program called
83 <code><a href="http://en.wikipedia.org/wiki/Lint_programming_tool">lint</a></code>
84 was developed that would scan a source file, looking for problems.</p>
85
86 <p>As the language matured, the definition of the language was
87 strengthened to eliminate some insecurities, and compilers got better
88 at issuing warnings. <code>lint</code> is no longer needed.</p>
89
90 <p><a href="http://javascript.crockford.com/">JavaScript</a> is a young-for-its-age
91 language. It was originally intended to do small tasks in webpages, tasks
92 for which Java was too heavy and clumsy. But JavaScript is a very capable
93 language, and it is now being used in larger projects. Many of the features
6735394d »
2010-12-02 Cleanup.
94 that were intended to make the language easy to use are troublesome when projects become complicated. A <code>lint</code> for JavaScript is needed: <a href="http://www.JSLint.com/"><code>JSLint</code></a>,
ca120a73 »
2010-11-12 first commit
95 a JavaScript syntax checker and validator.</p>
96
97 <p><code>JSLint</code> takes a JavaScript source and scans it. If it finds
98 a problem, it returns a message describing the problem and an approximate
99 location within the source. The problem is not necessarily a syntax error,
100 although it often is. <code>JSLint</code> looks at some style conventions
101 as well as structural problems. It does not prove that your program is
102 correct. It just provides another set of eyes to help spot problems.</p>
103
104 <p><code>JSLint</code> defines a professional subset of JavaScript, a stricter
105 language than that defined by <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm" target="ecma">Third
106 Edition of the <i>ECMAScript Programming Language Standard</i></a>. The
107 subset is related to recommendations found in <a href="http://javascript.crockford.com/code.html" target="sun"><i>Code
108 Conventions for the JavaScript Programming Language</i></a>. </p>
109 <p>JavaScript is a sloppy language, but inside it there is an elegant, better
110 language. <code>JSLint</code> helps you to program in that better language
6735394d »
2010-12-02 Cleanup.
111 and to avoid most of the slop. JSLint will reject programs that browsers will accept because JSLint is concerned with the quality of your code and browsers are not. You should accept all of JSLint's advice.</p>
112 <p><code>JSLint</code> can operate on JavaScript source, HTML source, CSS source, or <a href="http://www.JSON.org/">JSON</a>
ca120a73 »
2010-11-12 first commit
113 text.</p>
114 <h2 id=global>Global Variables</h2>
115 <p>JavaScript's <a href="http://yuiblog.com/blog/2006/06/01/global-domination/">biggest
116 problem</a> is its dependence on global variables, particularly implied
117 global variables. If a variable is not explicitly declared (usually with
118 the <code>var</code> statement), then JavaScript assumes that the variable
119 was global. This can mask misspelled names and other problems.</p>
120 <p><code>JSLint</code> expects that all variables and functions are declared
121 before they are used or invoked. This allows it to detect implied global
122 variables. It is also good practice because it makes programs easier to
123 read.</p>
124 <p>Sometimes a file is dependent on global variables and functions that
125 are defined elsewhere. You can identify these to <code>JSLint</code> with a <code>var</code> statement that lists the global functions and objects
126 that your program depends on. </p>
127 <p>A global declaration can look like this:</p>
128 <pre>var getElementByAttribute, breakCycles, hanoi;</pre>
9f0303cf »
2011-05-22 appear
129 <p>The declaration should appear near the top of the file. It must appear before the use of the variables
ca120a73 »
2010-11-12 first commit
130 it declares. </p>
131 <p>It is necessary to use a <code>var</code> statement to declare a variable before that variable is assigned to. </p>
44eec745 »
2011-06-14 Adrian
132 <p><code>JSLint</code> also recognizes a <code>/*global */</code> directive that can indicate to <code>JSLint</code> that variables used in this file were defined in other files. The comment can contain a comma separated list of names. Each name can optionally be followed by a colon and either <code>true</code> or <code>false</code>, <code>true</code> indicating that the variable may be assigned to by this file, and <code>false</code> indicating that assignment is not allowed (which is the default). The directive respects function scope.</p>
ca120a73 »
2010-11-12 first commit
133 <p id=browser>Some globals can be predefined for you. Select the <i>Assume
134 a browser</i> (<code>browser</code>) <a href="#options">option</a> to
135 predefine the standard global properties that are supplied by web browsers,
136 such as <code>document</code> and <code>addEventListener</code>. It has the same
137 effect as this comment:</p>
138 <blockquote>
df391013 »
2011-02-11 option.browser
139 <code>/*global
1ebebf33 »
2011-07-19 cleanup
140 clearInterval: false, clearTimeout: false, document: false, event: false, frames: false, history: false, Image: false, location: false, name: false, navigator: false, Option: false, parent: false, screen: false, setInterval: false, setTimeout: false, window: false, XMLHttpRequest: false
df391013 »
2011-02-11 option.browser
141 */</code></blockquote>
e752a553 »
2011-03-30 option.node
142 <p>Select the
143 <em>Assume console, alert, ...</em>
ca120a73 »
2010-11-12 first commit
144 (<code>devel</code>) <a href="#options">option</a> to predefine globals that are useful in development but that should be avoided in production, such as <code>console</code> and <code>alert</code>. It has the same
145 effect as this comment:</p>
396d71f6 »
2011-08-16 WSH
146 <pre>/*global alert: false, confirm: false, console: false, Debug: false, opera: false, prompt: false, WSH: false */</pre>
706c4858 »
2011-03-22 option.node
147 <p id=node>Select the
e752a553 »
2011-03-30 option.node
148 <em>Assume Node.js</em>
706c4858 »
2011-03-22 option.node
149 (<code>node</code>) <a href="#options">option</a> to predefine globals that are used in the Node.js environment<code></code>. It has the same
150 effect as this comment:</p>
816fc054 »
2011-09-26 node
151 <blockquote><code>/*global Buffer: false, clearInterval: false, clearTimeout: false, console: false, exports: false, global: false, module: false, process: false, querystring: false, require: false, setInterval: false, setTimeout: false, __filename: false, __dirname: false */</code></blockquote>
ca120a73 »
2010-11-12 first commit
152 <p id=rhino>Select the <i>Assume Rhino</i> (<code>rhino</code>) <a href="#options">option</a>
706c4858 »
2011-03-22 option.node
153 to predefine the global properties provided by the Rhino environment.
ca120a73 »
2010-11-12 first commit
154 It has the same effect as this statement:</p>
155 <blockquote>
156 <code>/*global defineClass: false, deserialize: false, gc: false, help: false, load: false, loadClass: false, print: false, quit: false, readFile: false, readUrl: false, runCommand: false, seal: false, serialize: false, spawn: false, sync: false, toint32: false, version: false */ </code>
157 </blockquote>
158 <p id=widget>Select the <i>Assume a Yahoo Widget</i> (<code>widget</code>)
159 <a href="#options">option</a> to predefine the global properties provided
160 by the Yahoo! Widgets environment. It has the same effect as this statement:</p>
161 <blockquote>
162 <code>/*global alert: true, animator: true, appleScript: true, beep: true, bytesToUIString: true, Canvas: true, chooseColor: true, chooseFile: true, chooseFolder: true, closeWidget: true, COM: true, convertPathToHFS: true, convertPathToPlatform: true, CustomAnimation: true, escape: true, FadeAnimation: true, filesystem: true, Flash: true, focusWidget: true, form: true, FormField: true, Frame: true, HotKey: true, Image: true, include: true, isApplicationRunning: true, iTunes: true, konfabulatorVersion: true, log: true, md5: true, MenuItem: true, MoveAnimation: true, openURL: true, play: true, Point: true, popupMenu: true, preferenceGroups: true, preferences: true, print: true, prompt: true, random: true, Rectangle: true, reloadWidget: true, ResizeAnimation: true, resolvePath: true, resumeUpdates: true, RotateAnimation: true, runCommand: true, runCommandInBg: true, saveAs: true, savePreferences: true, screen: true, ScrollBar: true, showWidgetPreferences: true, sleep: true, speak: true, Style: true, suppressUpdates: true, system: true, tellWidget: true, Text: true, TextArea: true, Timer: true, unescape: true, updateNow: true, URL: true, Web: true, widget: true, Window: true, XMLDOM: true, XMLHttpRequest: true, yahooCheckLogin: true, yahooLogin: true, yahooLogout: true */</code>
163 </blockquote>
164 <p id=windows>Select the <i>Assume Windows</i> (<code>windows</code>)
165 <a href="#options">option</a> to predefine the global properties provided by Microsoft Windows. It has the same effect as this statement:</p>
166 <blockquote>
396d71f6 »
2011-08-16 WSH
167 <p><code>/*global ActiveXObject: false, CScript: false, Debug: false, Enumerator: false, System: false, VBArray: false, WScript: false, WSH: false */</code></p>
ca120a73 »
2010-11-12 first commit
168 </blockquote>
169 <h2 id=semicolon>Semicolon</h2>
6735394d »
2010-12-02 Cleanup.
170 <p>JavaScript uses a C-like syntax which requires the use of semicolons to delimit certain
171 statements. JavaScript attempts to make those semicolons optional with a semicolon
172 insertion mechanism. This is dangerous because it can mask errors.</p>
ca120a73 »
2010-11-12 first commit
173 <p>Like C, JavaScript has <code>++</code> and <code>--</code> and <code>(</code> operators
174 which can be prefixes or suffixes. The disambiguation is done by the semicolon.</p>
175 <p>In JavaScript, a linefeed can be whitespace or it can act as a semicolon.
176 This replaces one ambiguity with another. </p>
177 <p><code>JSLint</code> expects that every statement be followed by <code>;</code> except
178 for <code>for</code>, <code>function</code>, <code>if</code>, <code>switch</code>, <code>try</code>, and
179 <code>while</code>. <code>JSLint</code> does not expect to see unnecessary semicolons or the
180 empty statement.</p>
181 <h2 id=comma>Comma</h2>
182 <p>The comma operator can lead to excessively tricky expressions. It can also
183 mask some programming errors.</p>
184 <p><code>JSLint</code> expects to see the comma used as a separator, but not as an
185 operator (except in the initialization and incrementation parts of the <code>for</code>
186 statement). It does not expect to see elided elements in array literals. Extra
187 commas should not be used. A comma should not appear after the last element
188 of an array literal or object literal because it can be misinterpreted by some
189 browsers. </p>
190 <h2 id=scope>Scope</h2>
191
192 <p>In many languages, a block introduces a scope. Variables introduced in
193 a block are not visible outside of the block.</p>
194
195 <p>In JavaScript, blocks do not introduce a scope. There is only function-scope.
196 A variable introduced anywhere in a function is visible everywhere in
197 the function. JavaScript's blocks confuse experienced programmers and
198 lead to errors because the familiar syntax makes a false promise.</p>
199
200 <p><code>JSLint</code> expects blocks with <code>function</code>, <code>if</code>,
201 <code>switch</code>, <code>while</code>, <code>for</code>, <code>do</code>,
202 and <code>try</code> statements and nowhere else. </p>
203 <p>In languages with block scope, it is usually recommended that variables
204 be declared at the site of first use. But because JavaScript does not
205 have block scope, it is wiser to declare all of a function's variables
206 at the top of the function. It is recommended that a single <code>var</code>
a27d17cd »
2011-06-09 Tolerate
207 statement be used per function. This can be declined with the <code>vars</code>
ca120a73 »
2010-11-12 first commit
208 <a href="#options">option</a>.</p>
209
210 <h2 id=required>Required Blocks</h2>
211
212 <p><code>JSLint</code> expects that <code>if</code>, <code>while</code>,
213 <code>do</code> and <code>for</code> statements will be made with blocks
214 <code>{</code>that is, with statements enclosed in braces<code>}</code>.</p>
215
216 <p>JavaScript allows an <code>if</code> to be written like this:</p>
217
218 <pre>if (<i>condition</i><code>)
219 </code><i>statement</i>;</pre>
220
221 <p>That form is known to contribute to mistakes in projects where many programmers
222 are working on the same code. That is why <code>JSLint</code> expects the use of
223 a block:</p>
224
225 <pre>if (<i>condition</i>) {
226 <i>statements</i>;
227 }</pre>
228
229 <p>Experience shows that this form is more resilient.</p>
230
231 <h2 id=expression>Expression Statements</h2>
232 <p>An expression statement is expected to be an assignment or a function/method
233 call or <code>delete</code>. All other expression statements are considered
234 to be errors.</p>
65313e21 »
2011-06-14 option.confusion
235 <h2 id="confusion">Type Confusion</h2>
236 <p>JSLint can do type inference. It can report cases were variables and properties are
237 used to house multiple types. The warning is <code>Type confusion:</code> {a} <code>and</code> {b}<code>.</code> where the {a} and {b} will be
238 replaced with the names of types.</p>
239 <p> It is usually easy to see what caused the
240 warning. In some cases, it can be very puzzling. In the puzzling cases, try
241 initializing your vars with typed values. For example, if you expect that <code>n</code> will
242 contain numbers, then write</p>
243 <pre>var n = 0;</pre>
244 <p>That should produce clearer warnings. </p>
245 <p>Type confusion is not necessarily an error, particularly in a language that
246 provides as much type freedom as this one does. But some inconsistencies are
247 errors, so type discipline might be something to consider adding to your
248 programming style. Also, the fastest JavaScript engines will slow down in the
249 presence of type confusion.
1ebebf33 »
2011-07-19 cleanup
250
65313e21 »
2011-06-14 option.confusion
251 To turn off these warnings, turn on the <i>Tolerate type confusion</i> <a href="#options">option</a>. </p>
ca120a73 »
2010-11-12 first commit
252 <h2 id=forin><code>for</code> <code>in</code></h2>
253 <p>The <code>for</code> <code>in</code> statement allows for looping through
254 the names of all of the properties of an object. <a href="http://yuiblog.com/blog/2006/09/26/for-in-intrigue/">Unfortunately,
d4189fff »
2011-03-11 properties
255 it also loops through all of the properties that were inherited through
ca120a73 »
2010-11-12 first commit
256 the prototype chain.</a> This has the bad side effect of serving up method
d4189fff »
2011-03-11 properties
257 functions when the interest is in data properties. If a program is written without awareness of this situation, then it can fail.</p>
ca120a73 »
2010-11-12 first commit
258 <p>The body of every <code>for</code> <code>in</code> statement should be
259 wrapped in an <code>if</code> statement that does filtering. It can select
260 for a particular type or range of values, or it can exclude functions,
261 or it can exclude properties from the prototype. For example,</p>
262 <pre>for (name in object) {
263 if (object.hasOwnProperty(name)) {
264 ....
265 }
266
267 }</pre>
268
269 <h2 id=switch><code>switch</code></h2>
270 <p>A <a href="http://yuiblog.com/blog/2007/04/25/id-rather-switch-than-fight/">common
271 error</a> in <code>switch</code> statements is to forget to place a <code>break</code>
272 statement after each case, resulting in unintended fall-through. <code>JSLint</code>
273 expects that the statement before the next <code>case</code> or <code>default</code>
274 is one of these: <code>break</code>, <code>return</code>, or <code>throw</code>.
275 </p>
276 <h2 id=var><code>var</code></h2>
277
278 <p>JavaScript allows <code>var</code> definitions to occur anywhere
279 within a function. <code>JSLint</code> is more strict.</p>
280
281 <p><code>JSLint</code> expects that a <code>var</code> will be declared
282 only once, and that it will be declared before it is used.</p>
283 <p><code></code><code>JSLint</code> expects that a <code>function</code>
284 will be declared before it is used.</p>
285 <p><code>JSLint</code> expects that parameters will not also be declared
286 as vars. </p>
287
288 <p><code>JSLint</code> does not expect the <code>arguments</code> array to be declared
289 as a <code>var</code>.</p>
290 <p><code>JSLint</code> does not expect that a var will be defined in a block.
291 This is because JavaScript blocks do not have block scope. This can have
292 unexpected consequences. Define all variables at the top of the function.</p>
293
294 <h2 id=with><code>with</code></h2>
295
296 <p>The <code>with</code> statement was intended to provide a shorthand in accessing
d4189fff »
2011-03-11 properties
297 properties in deeply nested objects. Unfortunately, it behaves <a href="http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/">very
298 badly</a> when setting new properties. Never use the <code>with</code> statement. Use
ca120a73 »
2010-11-12 first commit
299 a <code>var</code> instead.</p>
300
301 <p><code>JSLint</code> does not expect to see a <code>with</code> statement.</p>
302
303 <h2 id=assignment>=</h2>
304 <p><code>JSLint</code> does not expect to see an assignment statement in
305 the condition part of an <code>if</code> or <code>for</code> or <code>while</code>
306 <code></code> or <code>do</code> statement. This is because it is more
307 likely that </p>
308 <pre>if (a = b) {
309 ...
310 }</pre>
311 <p>was intended to be </p>
312 <pre>if (a == b) {
313 ...
314 }</pre>
315 <p>It is difficult to write correct programs while using idioms that are
9d80d800 »
2011-01-30 asignment unwrapped
316 hard to distinguish from obvious errors.</p>
ba257de6 »
2011-06-12 eqeq
317 <h2 id=eqeq>== and !=</h2>
ca120a73 »
2010-11-12 first commit
318 <p>The <code>==</code> and <code>!=</code> operators do type coercion before
319 comparing. This is bad because it causes <code>' \t\r\n' == 0</code> to
ca4cfb59 »
2011-06-14 Adrian
320 be <code>true</code>. This can mask type errors. JSLint cannot reliably determine if == is being used correctly, so it is best to not use <code>==</code> and != and to always use the more reliable <code>===</code> and <code>!==</code> operators instead. </p>
ca120a73 »
2010-11-12 first commit
321 <p align="left">If you only care that a value is <i>truthy</i> or <i>falsy</i>,
322 then use the short form. Instead of </p>
323 <pre align="left">(foo != 0)</pre>
324 <p align="left">just say </p>
325 <pre align="left">(foo)</pre>
326 <p align="left">and instead of</p>
327 <pre align="left">(foo == 0)</pre>
328 <p align="left"> say</p>
329 <pre align="left">(!foo)</pre>
ba257de6 »
2011-06-12 eqeq
330 <p>There is an <code>eqeq</code> <a href="#options">option</a> that allows the use of <code>==</code> and <code>!=</code>.</p>
ca120a73 »
2010-11-12 first commit
331 <h2 id=labels>Labels</h2>
332 <p>JavaScript allows any statement to have a label, and labels have a
333 separate name space. <code>JSLint</code> is more strict.</p>
334
335 <p><code>JSLint</code> expects labels only on statements that interact
336 with <code>break</code>: <code>switch</code>, <code>while</code>,
337 <code>do</code>, and <code>for</code>. <code>JSLint</code> expects that labels
338 will be distinct from vars and parameters.</p>
339
340 <h2 id=unreachable>Unreachable Code</h2>
341 <p><code>JSLint</code> expects that
342 a <code>return</code>, <code>break</code>, <code>continue</code>,
343 or <code>throw</code> statement will be followed by
344 a <code>}</code> or <code>case</code> or <code>default</code>.</p>
345
346 <h2 id=pluses>Confusing Pluses and Minuses</h2>
347
348 <p><code>JSLint</code> expects that <code>+</code> will not be followed by
349 <code>+</code> or <code>++</code>, and that <code>-</code> will not be followed
350 by <code>-</code> or <code>--</code>. A misplaced space can turn <code>+ +</code> into <code>++</code>, an error that is difficult to see. Use parens to avoid confusion..</p>
351 <h2 id=inc><code>++</code> and <code>--</code></h2>
352 <p>The <code>++</code> <small>(increment)</small> and <code>--</code> <small>(decrement)</small>
353 operators have been known to contribute to bad code by encouraging excessive
354 trickiness. They are second only to faulty architecture in enabling to
44eec745 »
2011-06-14 Adrian
355 viruses and other security menaces. Also, preincrement/postincrement confusion can produce off-by-one errors that are extremely difficult to diagnose. There is a <code>plusplus</code> <a href="#options">option</a>
a27d17cd »
2011-06-09 Tolerate
356 that allows the use of these operators.</p>
ca120a73 »
2010-11-12 first commit
357 <h2 id=bitwise>Bitwise Operators</h2>
358 <p>JavaScript does not have an integer type, but it does have bitwise operators.
359 The bitwise operators convert their operands from floating point to integers
360 and back, so they are not as efficient as in C or other languages. They
361 are rarely useful in browser applications. The similarity to the logical
362 operators can mask some programming errors. The <code>bitwise</code> <a href="#options">option</a>
a27d17cd »
2011-06-09 Tolerate
363 allows the use of these operators: <code>&lt;&lt; &gt;&gt; &gt;&gt;&gt;
ca120a73 »
2010-11-12 first commit
364 ~ &amp; |</code>.</p>
365 <h2 id=evil><code>eval</code> is evil</h2>
366 <p>The <code>eval</code> function (and its relatives, <code>Function</code>,
367 <code>setTimeout</code>, and <code>setInterval</code>) provide access
368 to the JavaScript compiler. This is sometimes necessary, but in most cases
369 it indicates the presence of extremely bad coding. The <code>eval</code>
370 function is the most misused feature of JavaScript.</p>
371
372 <h2 id=void><code>void</code></h2>
373 <p>In most C-like languages, <code>void</code> is a type. In
374 JavaScript, <code>void</code> is a prefix operator that always
375 returns <code>undefined</code>. <code>JSLint</code> does not expect to
376 see <code>void</code> because it is confusing and not very useful.</p>
377
378 <h2 id=regexp>Regular Expressions</h2>
379 <p>Regular expressions are written in a terse and cryptic notation. <code>JSLint</code>
380 looks for problems that may cause portability problems. It also attempts
381 to resolve visual ambiguities by recommending explicit escapement.</p>
382 <p>JavaScript's syntax for regular expression literals overloads the <code>/</code>
383 character. To avoid ambiguity, <code>JSLint</code> expects that the character
384 preceding a regular expression literal is a <code>(</code> or <code>=</code>
385 or <code>:</code> or <code>,</code> character. </p>
386 <h2 id=new>Constructors and <code>new</code></h2>
387 <p>Constructors are functions that are designed to be used with the <code>new</code>
388 prefix. The <code>new</code> prefix creates a new object based on the
389 function's <code>prototype</code>, and binds that object to the function's
390 implied <code>this</code> parameter. If you neglect to use the <code>new</code>
391 prefix, no new object will be made and <code>this</code> will be bound
392 to the global object. This is a <a href="http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/">serious
393 mistake</a>.</p>
394 <p><code>JSLint</code> enforces the convention that constructor functions
395 be given names with initial uppercase. <code>JSLint</code> does not expect
396 to see a function invocation with an initial uppercase name unless it
397 has the <code>new</code> prefix. <code>JSLint</code> does not expect to
398 see the <code>new</code> prefix used with functions whose names do not
a27d17cd »
2011-06-09 Tolerate
399 start with initial uppercase. This can be disabled with the <code>newcap</code>
ca120a73 »
2010-11-12 first commit
400 <a href="#options">option</a>.</p>
401 <p><code>JSLint</code> does not expect to see the wrapper forms <code>new Number</code>,
402 <code>new String</code>, <code>new Boolean</code>. </p>
403 <p><code>JSLint</code> does not expect to see <code>new Object</code> (use <code>{}</code>
404 instead). </p>
405 <p><code>JSLint</code> does not expect to see <code>new Array</code> (use <code>[]</code>
406 instead).</p>
598e67ff »
2011-06-28 /*properties */
407 <h2 id=type>Type Inference</h2>
408 <p>Type inference is being added to JSLint. The goal is to ultimately make JSLint more helpful in spotting type inconsistencies and confusions. If you do not want this service, then select the <code>confusion</code> <a href="#options">option</a>.</p>
409
410 <h2 id=properties>Properties</h2>
411 <p>Since JavaScript is a loosely-typed, dynamic-object language, it is not
412 possible to determine at compile time if property names are spelled correctly.
413 <code>JSLint</code> provides some assistance with this.</p>
414 <p>At the bottom of its report, <code>JSLint</code> displays a <code>/*properties*/</code>
415 comment. It contains all of the names and string literals that were used
416 with dot notation, subscript notation, and object literals to name the
417 properties of objects. You can look through the list for misspellings. Property
418 names that were only used once are shown in italics. This is to make misspellings
419 easier to spot.</p>
420 <p>You can copy the <code>/*properties*/</code> comment into your script file.
421 <code>JSLint</code> will check the spelling of all property names against
422 the list. That way, you can have <code>JSLint</code> look for misspellings
423 for you. The directive respects function scope.</p>
424 <p>JSLint allows the property names to be annotated with types: <code>array</code>, <code>boolean</code>, <code>function</code>, <code>number</code>, <code>object</code>, <code>regexp</code>, <code>string</code>, or <code>*</code> (a wildcard allowing any type). A function type can be followed by another type, indicating a function's return type.</p>
425 <p>For example,</p>
426 <pre>/*properties
427 charAt: function string, slice: function *
428 */</pre>
429
ca120a73 »
2010-11-12 first commit
430 <h2 id=unsafe>Unsafe Characters</h2>
431 <p> There are characters that are handled inconsistently in browsers, and
432 so must be escaped when placed in strings. </p>
433 <pre>\u0000-\u001f
434 \u007f-\u009f
435 \u00ad
436 \u0600-\u0604
437 \u070f
438 \u17b4
439 \u17b5
440 \u200c-\u200f
441 \u2028-\u202f
442 \u2060-\u206f
443 \ufeff
444 \ufff0-\uffff</pre>
445 <h2 id=not>Not Looked For</h2>
446
447 <p><code>JSLint</code> does not do flow analysis to determine that variables are assigned
448 values before used. This is because variables are given a value (<code>undefined</code>)
6735394d »
2010-12-02 Cleanup.
449 that is a reasonable default for many applications.</p>
ca120a73 »
2010-11-12 first commit
450
451 <p><code>JSLint</code> does not do any kind of global analysis. It does
452 not attempt to determine that functions used with <code>new</code> are
453 really constructors (<a href="#new">except by enforcing capitalization
d4189fff »
2011-03-11 properties
454 conventions</a>), or that property names are spelled correctly (<a href="#properties">except
455 for matching against the <code>/*properties */</code> comment</a>).</p>
ca120a73 »
2010-11-12 first commit
456 <h2 id=html>HTML</h2>
457 <p><code>JSLint</code> is able to handle HTML text. It can inspect the JavaScript content
458 contained within <code>&lt;script&gt;</code>...<code>&lt;/script&gt;</code> tags. It
459 also inspects the HTML content, looking for problems that are known to interfere
460 with JavaScript:</p>
461 <ul>
462 <li>All tag names must be in lower case.</li>
463 <li>All tags that can take a close tag (such as <code>&lt;/p&gt;</code>)
464 must have a close tag.</li>
465 <li>All tags are correctly nested.</li>
466 <li>The entity <code>&amp;lt;</code> must be used for literal <code>'&lt;'</code>.</li>
467 </ul>
468 <p><code>JSLint</code> is less anal than the sycophantic conformity demanded
469 by XHTML, but more strict than the popular browsers. </p>
470 <p><code>JSLint</code> also checks for the occurrence of<code> '&lt;/' </code>in
471 string literals. You should always write<code> '&lt;\/' </code>instead.
472 The extra backslash is ignored by the JavaScript compiler but not by the
473 HTML parser. Tricks like this should not be necessary, and yet they are.</p>
474 <p>There is a <code>cap</code> <a href="#options">option</a> that allows
44eec745 »
2011-06-14 Adrian
475 use of uppercase tag names. There is also an <code>on</code> <a href="#options">option</a>
ca120a73 »
2010-11-12 first commit
476 that allows the use of inline HTML event handlers.</p>
477 <p>There is a <code>fragment</code> <a href="#options">option</a> that can
478 inspect a well formed HTML fragment. If the <code>adsafe</code> <a href="#options">option</a>
479 is also used, then the fragment must be a <code>&lt;div&gt;</code> that
480 conforms to the <a href="http://www.ADsafe.org/">ADsafe</a> widget rules.</p>
481 <h2 id=css>CSS</h2>
482 <p><code>JSLint</code> can inspect CSS files. It expects the first line
483 of a CSS file to be </p>
484 <pre>@charset &quot;UTF-8&quot;;</pre>
485 <p>This feature is experimental. Please report any problems or limitations.
486 There is a <code>css</code> <a href="#options">option</a> that will tolerate
598e67ff »
2011-06-28 /*properties */
487 some of the non-standard-but-customary workarounds. </p>
ca120a73 »
2010-11-12 first commit
488
489 <h2 id=options>Options</h2>
490 <p><code>JSLint</code> provides several options that control its operation and
491 its sensitivity. In the <a href="http://www.JSLint.com/">web edition</a>, the
a27d17cd »
2011-06-09 Tolerate
492 options are selected with several checkboxes and two fields. </p>
ca120a73 »
2010-11-12 first commit
493 <p>It also provides assistance in constructing <code>/*jslint*/</code>
494 comments.
495 </p>
496 <p>When <code>JSLINT</code> is called as a function, it accepts an <code>option</code> object
497 parameter that allows you to determine the subset of JavaScript that is
498 acceptable to you. The web page version of <code>JSLint</code> at <a href="http://www.JSLint.com/">http://www.JSLint.com/</a>
499 does this for you. </p>
500 <p>Options can also be specified within a script with a <code>/*jslint */</code>
475768b9 »
2011-03-06 /*properties*/ and /*global*/ now respect function scope
501 directive:</p>
ca120a73 »
2010-11-12 first commit
502 <pre>/*jslint nomen: true, debug: true,
a27d17cd »
2011-06-09 Tolerate
503 evil: false, vars: true */</pre>
ca120a73 »
2010-11-12 first commit
504 <p>An option specification starts with <code>/*jslint</code>. Notice that
505 there is no space before the <code>j</code>. The specification contains
506 a sequence of name value pairs, where the names are <code>JSLint</code>
507 options, and the values are <code>true</code> or <code>false</code>. The
508 <code>indent</code> <a href="#options">option</a> can take a number. A <code>/*jslint */</code>
475768b9 »
2011-03-06 /*properties*/ and /*global*/ now respect function scope
509 comment takes precedence over the <code>option</code> object. The directive respects function scope.</p>
ca120a73 »
2010-11-12 first commit
510 <table>
511 <tbody>
512 <tr>
513 <th>Description</th>
514 <th><code>option</code></th>
515 <th>Meaning</th>
516 </tr>
517 <tr>
518 <td>ADsafe</td>
519 <td><code>adsafe</code></td>
520 <td><code>true</code> if <a href="http://www.ADsafe.org/">AD<span style="color: blue;">safe</span></a>
f690208a »
2011-12-08 adsafe is used with the option object, but not with the /*jslint */ c…
521 rules should be enforced. See <a href="http://www.ADsafe.org/">http://www.ADsafe.org/</a>. <code>adsafe</code> is used with the <code>option</code> object, but not
522 with the <code>/*jslint */</code> comment. </td>
ca120a73 »
2010-11-12 first commit
523 </tr>
524 <tr>
a27d17cd »
2011-06-09 Tolerate
525 <td>Tolerate bitwise operators </td>
ca120a73 »
2010-11-12 first commit
526 <td><code>bitwise</code></td>
a27d17cd »
2011-06-09 Tolerate
527 <td><code>true</code> if bitwise operators should be allowed. <a href="#bitwise"><small>(more)</small></a></td>
ca120a73 »
2010-11-12 first commit
528 </tr>
529 <tr>
530 <td>Assume a browser </td>
531 <td><code>browser</code></td>
532 <td><code>true</code> if the standard browser globals should be predefined.
533 <a href="#browser"><small>(more)</small></a> </td>
534 </tr>
535 <tr>
536 <td>Tolerate HTML case </td>
537 <td><code>cap</code></td>
44eec745 »
2011-06-14 Adrian
538 <td><code>true</code> if uppercase HTML should be allowed.</td>
ca120a73 »
2010-11-12 first commit
539 </tr>
540 <tr>
65313e21 »
2011-06-14 option.confusion
541 <td>Tolerate type confusion<br>
542 </td>
543 <td><code>confusion</code></td>
544 <td><code>true</code> if variables and properties are allowed to contain more than one type of value.</td>
545 </tr>
546 <tr>
3c8016ec »
2011-02-02 option.continue
547 <td>Tolerate <code>continue</code></td>
548 <td><code>continue</code></td>
549 <td><code>true</code> if the <code>continue</code> statement should be allowed.</td>
550 </tr>
551 <tr>
ca120a73 »
2010-11-12 first commit
552 <td>Tolerate CSS workarounds</td>
553 <td><code>css</code></td>
554 <td><code>true</code> if CSS workarounds should be tolerated. <a href="#css"><small>(more)</small></a></td>
555 </tr>
556 <tr>
557 <td>Tolerate debugger statements</td>
558 <td><code>debug</code></td>
559 <td><code>true</code> if <code>debugger</code> statements should be
560 allowed. Set this option to <code>false</code> before going into production.</td>
561 </tr>
562 <tr>
563 <td>Assume <code>console</code>, <code>alert</code>, ...</td>
564 <td><code>devel</code></td>
565 <td><code>true</code> if browser globals that are useful in development should be
ef3710d4 »
2011-11-19 more
566 predefined. <small>(<a href="#devel">more</a>)</small></td>
ca120a73 »
2010-11-12 first commit
567 </tr>
568 <tr>
ba257de6 »
2011-06-12 eqeq
569 <td>Tolerate <code>==</code> and <code>!=</code></td>
570 <td><code>eqeq</code></td>
ef3710d4 »
2011-11-19 more
571 <td><code>true</code> if the <code>==</code> and <code>!=</code> operators should be tolerated. <small>(<a href="#eqeq">more</a>)</small></td>
1ebebf33 »
2011-07-19 cleanup
572 </tr>
ba257de6 »
2011-06-12 eqeq
573 <tr>
5675d2c6 »
2011-01-07 http://tech.groups.yahoo.com/group/jslint_com/message/1730
574 <td>Tolerate ES5 syntax</td>
575 <td><code>es5</code></td>
1ebebf33 »
2011-07-19 cleanup
576 <td><code>true</code> if ES5 syntax should be allowed.
577 It is likely that programs using this option will produce syntax errors on ES3 systems.</td>
ca120a73 »
2010-11-12 first commit
578 </tr>
579 <tr>
580 <td>Tolerate <code>eval</code> </td>
581 <td><code>evil</code></td>
582 <td><code>true</code> if <code>eval</code> should be allowed. <a href="#evil"><small>(more)</small></a></td>
583 </tr>
584 <tr>
585 <td>Tolerate unfiltered for in </td>
586 <td><code>forin</code></td>
587 <td><code>true</code> if unfiltered <code>for</code> <code>in</code>
588 statements should be allowed. <a href="#forin"><small>(more)</small></a></td>
589 </tr>
590 <tr>
591 <td>Tolerate HTML fragments </td>
592 <td><code>fragment</code></td>
593 <td><code>true</code> if HTML fragments should be allowed. <a href="#html"><small>(more)</small></a></td>
594 </tr>
595 <tr>
5675d2c6 »
2011-01-07 http://tech.groups.yahoo.com/group/jslint_com/message/1730
596 <td>Strict white space indentation</td>
597 <td><code>indent</code></td>
4310f67e »
2011-08-06 indent
598 <td>The number of spaces used for indentation (default is 4).</td>
ca120a73 »
2010-11-12 first commit
599 </tr>
600 <tr>
5675d2c6 »
2011-01-07 http://tech.groups.yahoo.com/group/jslint_com/message/1730
601 <td>Maximum number of errors</td>
602 <td><code>maxerr</code></td>
0c4a9d6a »
2011-06-09 .
603 <td>The maximum number of warnings reported. (default is 50)</td>
ca120a73 »
2010-11-12 first commit
604 </tr>
605 <tr>
606 <td>Maximum line length</td>
607 <td><code>maxlen</code></td>
0c4a9d6a »
2011-06-09 .
608 <td>The maximum number of characters in a line.</td>
ca120a73 »
2010-11-12 first commit
609 </tr>
610 <tr>
a27d17cd »
2011-06-09 Tolerate
611 <td>Tolerate uncapitalized constructors</td>
ca120a73 »
2010-11-12 first commit
612 <td><code>newcap</code></td>
a27d17cd »
2011-06-09 Tolerate
613 <td><code>true</code> if Initial Caps with constructor
614 functions is optional. <a href="#new"><small>(more)</small></a></td>
ca120a73 »
2010-11-12 first commit
615 </tr>
616 <tr>
706c4858 »
2011-03-22 option.node
617 <td>Assume Node.js</td>
618 <td><code>node</code></td>
0c4a9d6a »
2011-06-09 .
619 <td><code>true</code> if Node.js globals should be predefined. <a href="#node"><small>(more)</small></a></td>
706c4858 »
2011-03-22 option.node
620 </tr>
621 <tr>
a27d17cd »
2011-06-09 Tolerate
622 <td>Tolerate dangling _ in identifiers </td>
706c4858 »
2011-03-22 option.node
623 <td><code>nomen</code></td>
0c4a9d6a »
2011-06-09 .
624 <td><code>true</code> if names should not be checked for initial or trailing underbars.</td>
706c4858 »
2011-03-22 option.node
625 </tr>
626 <tr>
ca120a73 »
2010-11-12 first commit
627 <td>Tolerate HTML event handlers </td>
628 <td><code>on</code></td>
629 <td><code>true</code> if HTML event handlers should be allowed. <a href="#html"><small>(more)</small></a></td>
630 </tr>
631 <tr>
632 <td>Stop on first error </td>
633 <td><code>passfail</code></td>
634 <td><code>true</code> if the scan should stop on first error.</td>
635 </tr>
636 <tr>
a27d17cd »
2011-06-09 Tolerate
637 <td>Tolerate <code>++</code> and <code>--</code> </td>
ca120a73 »
2010-11-12 first commit
638 <td><code>plusplus</code></td>
639 <td><code>true</code> if <code>++</code> and <code>--</code> should
a27d17cd »
2011-06-09 Tolerate
640 be allowed. <a href="#inc"><small>(more)</small></a></td>
ca120a73 »
2010-11-12 first commit
641 </tr>
642 <tr>
643 <td>Predefined <small>( , separated)</small></td>
644 <td><code>predef</code></td>
6735394d »
2010-12-02 Cleanup.
645 <td>An array of strings, the names of predefined global variables, or an object whose keys are global variable names, and whose values are booleans that determine if each variable is assignable (also see <a href="#global">global</a>). <code>predef</code> is used with the <code>option</code> object, but not
00d8d1f2 »
2010-12-02 option.predef
646 with the <code>/*jslint */</code> comment. You can also use the <code>var</code>
ca120a73 »
2010-11-12 first commit
647 statement to declare global variables in a script file.</td>
648 </tr>
649 <tr>
a27d17cd »
2011-06-09 Tolerate
650 <td>Tolerate <code>.</code> and <code>[^</code>...<code>]</code>. in /RegExp/ </td>
ca120a73 »
2010-11-12 first commit
651 <td><code>regexp</code></td>
a27d17cd »
2011-06-09 Tolerate
652 <td><code>true</code> if <code>.</code> and <code>[^</code>...<code>]</code> should be allowed in RegExp
8d1c4eb6 »
2011-01-10 clarification
653 literals. They match more material than might be expected, allowing attackers to confuse applications. These forms should not be used when validating in secure applications. </td>
ca120a73 »
2010-11-12 first commit
654 </tr>
655 <tr>
656 <td>Assume Rhino </td>
657 <td><code>rhino</code></td>
658 <td><code>true</code> if the <a href="http://www.mozilla.org/rhino/">Rhino</a>
659 environment globals should be predefined. <a href="#rhino"><small>(more)</small></a></td>
660 </tr>
661 <tr>
662 <td>Safe Subset </td>
663 <td><code>safe</code></td>
664 <td><code>true</code> if the safe subset rules are enforced. These rules
665 are used by <a href="http://www.ADsafe.org/">ADsafe</a>. It enforces
f690208a »
2011-12-08 adsafe is used with the option object, but not with the /*jslint */ c…
666 the safe subset rules but not the widget structure rules. <code>safe</code> is used with the <code>option</code> object, but not
667 with the <code>/*jslint */</code> comment. </td>
ca120a73 »
2010-11-12 first commit
668 </tr>
669 <tr>
a27d17cd »
2011-06-09 Tolerate
670 <td> Tolerate missing&nbsp;<code>'use strict'</code>&nbsp;pragma </td>
671 <td><code>sloppy</code></td>
672 <td><code>true</code> if the ES5 <code><a href="http://www.yuiblog.com/blog/2010/12/14/strict-mode-is-coming-to-town/">'use strict';</a></code> pragma
0c4a9d6a »
2011-06-09 .
673 is not required. Do not use this pragma unless you know what you are doing.</td>
ca120a73 »
2010-11-12 first commit
674 </tr>
675 <tr>
676 <td>Tolerate inefficient subscripting<br>
677 </td>
678 <td><code>sub</code></td>
679 <td><code>true</code> if subscript notation may be used for expressions
680 better expressed in dot notation.</td>
681 </tr>
682 <tr>
a27d17cd »
2011-06-09 Tolerate
683 <td> Tolerate misordered definitions </td>
ca120a73 »
2010-11-12 first commit
684 <td><code>undef</code></td>
a27d17cd »
2011-06-09 Tolerate
685 <td><code>true</code> if variables and functions need not be declared before used. <a href="#undefined"><small>(more)</small></a></td>
ca120a73 »
2010-11-12 first commit
686 </tr>
687 <tr>
0b060c1a »
2011-06-09 unparam
688 <td> Tolerate unused parameters</td>
689 <td><code>unparam</code></td>
0c4a9d6a »
2011-06-09 .
690 <td><code>true</code> if warnings should not be given for unused parameters.</td>
0b060c1a »
2011-06-09 unparam
691 </tr>
692 <tr>
693 <td>Tolerate many&nbsp;<tt>var</tt>&nbsp;statements per function</td>
694 <td><code>vars</code></td>
695 <td><code>true</code> if multiple <code>var</code> statement per function
696 should be allowed. <a href="#scope"><small>(more)</small></a></td>
697 </tr>
698 <tr>
a27d17cd »
2011-06-09 Tolerate
699 <td> Tolerate messy white space</td>
ca120a73 »
2010-11-12 first commit
700 <td><code>white</code></td>
0b060c1a »
2011-06-09 unparam
701 <td><code>true</code> if strict whitespace rules should be ignored.</td>
ca120a73 »
2010-11-12 first commit
702 </tr>
703 <tr>
704 <td>Assume a Yahoo Widget </td>
705 <td><code>widget</code></td>
706 <td><code>true</code> if the <a href="http://widgets.yahoo.com/gallery/view.php?widget=37484">Yahoo
707 Widgets</a> globals should be predefined. <a href="#widget"><small>(more)</small></a></td>
708 </tr>
709 <tr>
0b060c1a »
2011-06-09 unparam
710 <td>Assume Windows</td>
ca120a73 »
2010-11-12 first commit
711 <td><code>windows</code></td>
1ebebf33 »
2011-07-19 cleanup
712 <td><code>true</code> if the Windows globals should be predefined. <a href="#windows"><small>(more)</small></a></td>
ca120a73 »
2010-11-12 first commit
713 </tr>
714 </tbody>
715 </table>
716 <h2 id=report>Report</h2>
717
718 <p>If <code>JSLint</code> is able to complete its scan, it generates a function
719 report. It lists for each function:</p>
720
721 <ul>
722 <li>The line number on which it starts.</li>
723 <li>Its name. In the case of anonymous functions, <code>JSLint</code>
0c4a9d6a »
2011-06-09 .
724 will 'guess' the name.</li>
ca120a73 »
2010-11-12 first commit
725 <li>The parameters.</li>
726 <li><i>Closure</i>: The variables and parameters that are declared in
727 the function that are used by its inner functions.</li>
728 <li><i>Variables</i>: The variables that are declared in the function
729 that are used only by the function.</li>
730 <li><i>Exceptions</i>: The variables that are declared by try statements.</li>
731 <li><i>Unused</i>: The variables that are declared in the function that
732 are not used. This may be an indication of an error.</li>
733 <li><i>Outer</i>: Variables used by this function that are declared in
734 another function.</li>
735 <li><i>Global</i>: Global variables that are used by this function. Keep
736 these to a minimum.</li>
737 <li><i>Label</i>: Statement labels that are used by this function.</li>
738 </ul>
d4189fff »
2011-03-11 properties
739 <p>The report will also include a list of all of the <a href="#properties">property
ca120a73 »
2010-11-12 first commit
740 names</a> that were used. There is a <a href="msgs.html">list of <code>JSLint</code>
741 messages</a>.</p>
742 <h2 id=feedback>Feedback</h2>
743 <p>Please let me know if <code>JSLint</code> is useful for you. Is it too
744 strict? Is there a check or a report that could help you to improve the
745 quality of your programs? <a href="mailto:douglas@crockford.com">douglas@crockford.com</a></p>
746
747 <p>I intend to continue to adapt <code>JSLint</code> based on your comments.
748 Keep watching for improvements. Updates are announced at <a href="http://tech.groups.yahoo.com/group/jslint_com/">http://tech.groups.yahoo.com/group/jslint_com/</a>.</p>
749
750 <h2 id=try>Try it</h2>
751
752 <p><a href="http://www.JSLint.com" target="_blank">Try it.</a> Paste your script
753 into the window and click the
754 <a href="http://www.JSLint.com" target=jslint><input type="button" value="JSLint"></a>
755 button. The analysis is done by a script running on your machine.
598e67ff »
2011-06-28 /*properties */
756 Your script is not sent over the network. You can set the <a href="#options">options</a> used. </p>
bdd35767 »
2010-12-08 k
757 <p>
758 JSLint is written entirely in JavaScript, so it can run anywhere that JavaScript can run. See for example <a href="http://tech.groups.yahoo.com/group/jslint_com/database?method=reportRows&tbl=1">http://tech.groups.yahoo.com/group/jslint_com/database?method=reportRows&amp;tbl=1</a>.</p>
ca120a73 »
2010-11-12 first commit
759 <h2 id=implementation>Implementation</h2>
760 <p><code>JSLint</code> uses a <a href="http://javascript.crockford.com/tdop/tdop.html">Pratt
761 Parser (Top Down Operator Precedence)</a>. It is written in JavaScript.
35ec4a53 »
2010-11-18 groove
762 The full source code is available: <a href="https://github.com/douglascrockford/JSLint">https://github.com/douglascrockford/JSLint</a>.</p>
ca120a73 »
2010-11-12 first commit
763 <a href="http://www.JSLint.com/"><img src="jslintpill.gif" width="36" height="17" border="0"></a>
764 <a href="http://www.ADsafe.org/"><img src="adsafepill.gif" width="36" height="17" border="0"></a>
765 <a href="http://www.JSON.org/"><img src="jsonpill.gif" width="36" height="17" border="0"></a>
766 </body>
767 </html>
Something went wrong with that request. Please try again.