Skip to content

Commit 8f612b3

Browse files
committed
Automatic merge from master.
1 parent 2e1ac8c commit 8f612b3

File tree

2 files changed

+116
-48
lines changed

2 files changed

+116
-48
lines changed

css/garden.css

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,30 @@ a abbr {
301301
opacity: 0.85;
302302
}
303303

304+
aside p {
305+
font-size: 13px;
306+
}
307+
}
308+
309+
@media screen and (max-device-width: 480px) {
310+
body > div {
311+
padding-right: 30px;
312+
}
313+
314+
article {
315+
font-size: 15px;
316+
width: 100%;
317+
}
318+
319+
aside {
320+
position: static;
321+
width: auto;
322+
margin: 30px;
323+
padding: 0.6em 1em 0.625em;
324+
border-top: 1px solid #9eabb7;
325+
opacity: 0.85;
326+
}
327+
304328
aside p {
305329
font-size: 13px;
306330
}

index.html

Lines changed: 92 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,64 +1360,108 @@ <h1>JavaScript Garden</h1>
13601360

13611361
<article><section><header><h2 id="semicolon">Automatic semicolon insertion <a href="#intro">#top</a></h2></header>
13621362
<p>Although JavaScript has C style syntax, it does <strong>not</strong> enforce the use of
1363-
semicolons in the source code. Since the parser still needs semicolons in order
1364-
to be able to figure out what the code should do, it inserts them
1365-
<strong>automatically</strong>.</p>
1366-
<p>When the parser encounters an error due to newline that is not preceded by a
1367-
semicolon, it will insert a semicolon automatically and try again. When the
1368-
parser still hits an error, it will raise it, otherwise it will simply proceed.</p>
1369-
<p>The automatic insertion of semicolon is considered to be one of <strong>biggest</strong>
1370-
design flaws in the language. It makes the below code work, but with a
1371-
completely different result than intended.</p>
1372-
<pre><code>return
1373-
{
1374-
foo: 1
1375-
}
1363+
semicolons in the source code, it is possible to omit them.</p>
1364+
<p>But JavaScript is not a semicolon-less language, it in fact needs the
1365+
semicolons in order to understand the source code. Therefore the JavaScript
1366+
parser <strong>automatically</strong> inserts them whenever it encounters a parse
1367+
error due to a missing semicolon.</p>
1368+
<pre><code>var foo = function() {
1369+
} // parse error, semicolon expected
1370+
test()
1371+
</code></pre>
1372+
<p>Insertion happens, and the parser tries again.</p>
1373+
<pre><code>var foo = function() {
1374+
}; // no error, parser continues
1375+
test()
13761376
</code></pre>
1377-
<p>After the JavaScript parser fixed it, this will <strong>not</strong> return an object which
1378-
has a property called <code>foo</code>, it will instead simply return <code>undefined</code>.</p>
1379-
</section><section><header><h3>How the parser "fixes" missing semicolons</h3></header>
1380-
<pre><code>return // Error, semicolon expected. Automatic insertion happens
1381-
{ // Block syntax is handle just fine
1377+
<p>The automatic insertion of semicolon is considered to be one of <strong>biggest</strong>
1378+
design flaws in the language as it <em>can</em> change the behavior of code.</p>
1379+
</section><section><header><h3>How it works</h3></header>
1380+
<p>The code below has no semicolons in it, so it is up to the parser to decide where
1381+
to insert them.</p>
1382+
<pre><code>(function(window, undefined) {
1383+
function test(options) {
1384+
log('testing!')
1385+
1386+
(options.list || []).forEach(function(i) {
1387+
1388+
})
1389+
1390+
options.value.test(
1391+
'long string to pass here',
1392+
'and another long string to pass'
1393+
)
1394+
1395+
return
1396+
{
1397+
foo: function() {}
1398+
}
1399+
}
1400+
window.test = test
13821401

1383-
// foo is not interpreted as property name, but as a label
1384-
foo: 1 // JavaScript supports single expression evaluation
1385-
// So 1 evaluates to 1 and no error is being raised
1402+
})(window)
13861403

1387-
} // Automatic semicolon insertion
1388-
</code></pre>
1389-
<p>After the parser has done its "magic", the resulting code has completely
1390-
different behavior.</p>
1391-
<pre><code>return; // implicitly returns undefined
1404+
(function(window) {
1405+
window.someLibrary = {}
13921406

1393-
// dead code
1394-
{
1395-
foo: 1
1396-
};
1407+
})(window)
13971408
</code></pre>
1398-
</section><section><header><h3>Missing semicolons and evaluation</h3></header>
1399-
<pre><code>var foo = function() {
1400-
} // missing semicolon after assignment
1409+
<p>Below is the result of the parser's "guessing" game.</p>
1410+
<pre><code>(function(window, undefined) {
1411+
function test(options) {
14011412

1402-
(function() {
1403-
// do something in it's own scope
1404-
})();
1405-
</code></pre>
1406-
<p>Again, the above code will behave <strong>drastically different</strong>.</p>
1407-
<pre><code>var foo = function(){
1413+
// Not inserted, lines got merged
1414+
log('testing!')(options.list || []).forEach(function(i) {
14081415

1409-
}( // The parser does NOT insert a semicolon here
1410-
// call the anonymous function and pass another function in
1411-
function() {
1416+
}); // &lt;- inserted
1417+
1418+
options.value.test(
1419+
'long string to pass here',
1420+
'and another long string to pass'
1421+
); // &lt;- inserted
1422+
1423+
return; &lt;- inserted, breaks the return statement
1424+
{
1425+
foo: function() {}
1426+
}; // &lt;- inserted
14121427
}
1413-
)() // now call the result of the previous call
1428+
window.test = test; // &lt;- inserted
1429+
1430+
// The lines got merged again
1431+
})(window)(function(window) {
1432+
window.someLibrary = {}; //&lt;- inserted
1433+
1434+
})(window); //&lt;- inserted
1435+
</code></pre>
1436+
<p>The parser drastically changed the behavior of the code above, in certain cases
1437+
it does the <strong>wrong</strong> thing.</p>
1438+
</section><section><header><h3>Leading parenthesis</h3></header>
1439+
<p>In case of a leading parenthesis, the parse will <strong>not</strong> insert a semicolon.</p>
1440+
<pre><code>log('testing!')
1441+
(options.list || []).forEach(function(i) {})
1442+
</code></pre>
1443+
<p>This code gets transformed into one line.</p>
1444+
<pre><code>log('testing!')(options.list || []).forEach(function(i) {})
1445+
</code></pre>
1446+
<p>Chances are <strong>very</strong> high that <code>log</code> does <strong>not</strong> return a function, therefore the
1447+
above will yield <code>TypeError</code> saying that <code>undefined is not a function</code>.</p>
1448+
</section><section><header><h3>Broken <code>return</code> statements</h3></header>
1449+
<p>The JavaScript parse also does not correctly handle return statements which are
1450+
followed by a new line. </p>
1451+
<pre><code>return;
1452+
{ // gets interpreted as a block
1453+
1454+
// a label and a single expression statement
1455+
foo: function() {}
1456+
};
14141457
</code></pre>
1458+
<p>Instead it produces the above, that is simply a silent error</p>
14151459
</section><section><header><h3>In conclusion</h3></header>
1416-
<p>Semicolons should <strong>never</strong> be omitted, it is also recommended to keep braces
1417-
on the same line with their associated statements and never omit them for one
1418-
line <code>if</code> / <code>else</code> statements. This will not only improve the consistency of the
1419-
code, it will also prevent the JavaScript parser from applying too much "magic"
1420-
to the code.</p></section></article>
1460+
<p>It is highly recommended to <strong>never</strong> omit semicolons, it is also advocated to
1461+
keep braces on the same line with their corresponding statements and to never omit
1462+
them for one single-line <code>if</code> / <code>else</code> statements. Both of these measures will
1463+
not only improve the consistency of the code, they will also prevent the
1464+
JavaScript parser from changing its behavior.</p></section></article>
14211465
<footer>
14221466
<p>
14231467
Copyright &copy; 2011.

0 commit comments

Comments
 (0)