Skip to content

Commit 327059a

Browse files
committed
better documentation for general patterns
1 parent fa1caed commit 327059a

14 files changed

+197
-105
lines changed

general-patterns/access-to-global-object.html

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,19 @@
77
<body>
88
<script>
99
/* Title: Access to the Global Object
10-
Description: access the global object without hard-coding the identifier window
11-
*/
10+
* Description: access the global object without hard-coding the identifier window
11+
*/
1212

1313
// access to the Global Object
1414
// this should work in ES3, ES5 and ES5-strict.
1515
var global = (function () {
1616
return this || (1,eval)('this');
1717
}());
1818

19-
// reference
19+
// Test Cases
20+
// http://jsperf.com/globalx
21+
22+
// References
2023
// http://net.tutsplus.com/tutorials/javascript-ajax/the-essentials-of-writing-high-quality-javascript/
2124
</script>
2225
</body>

general-patterns/avoiding-eval.html

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,36 @@
77
<body>
88
<script>
99
/* Title: Avoiding eval()
10-
Description: avoid using eval()
11-
*/
10+
* Description: avoid using eval()
11+
*/
1212

13-
// antipattern
13+
// antipattern 1
1414
var property = "name";
1515
alert(eval("obj." + property));
1616

17-
// preferred
17+
18+
// preferred 1
1819
var property = "name";
1920
alert(obj[property]);
2021

2122

22-
// antipatterns
23+
/* antipattern 2
24+
* It's also important to remember that passing strings to setInterval(), setTimeout(),
25+
* and the Function() constructor is, for the most part, similar to using eval() and therefore should be avoided.
26+
*/
2327
setTimeout("myFunc()", 1000);
2428
setTimeout("myFunc(1, 2, 3)", 1000);
2529

26-
// preferred
30+
31+
// preferred 2
2732
setTimeout(myFunc, 1000);
2833
setTimeout(function () {
2934
myFunc(1, 2, 3);
3035
}, 1000);
3136
// in supported browsers (i.e. not IE)
3237
setTimeout(myFunc, 1000, 1, 2, 3);
3338

34-
// reference
39+
// References
3540
// http://net.tutsplus.com/tutorials/javascript-ajax/the-essentials-of-writing-high-quality-javascript/
3641
</script>
3742
</body>

general-patterns/avoiding-implied-typecasting.html

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,37 @@
77
<body>
88
<script>
99
/* Title: Implied Typecasting
10-
Description: avoid implied typecasting
11-
*/
10+
* Description: avoid implied typecasting
11+
*/
1212

1313
var zero = 0;
1414

15-
// antipattern
15+
/* antipattern
16+
* JavaScript implicitly typecasts variables when you compare them.
17+
* That's why comparisons such as false == 0 or "" == 0 return true.
18+
*/
1619
if (zero == false) {
1720
// this block is executed...
1821
}
1922

20-
// correct way
23+
24+
// preferred
25+
/* To avoid confusion caused by the implied typecasting,
26+
* always use the === and !== operators that check both the values and the type of the expressions you compare
27+
*/
2128
if (zero === false) {
2229
// not executing because zero is 0, not false
2330
}
2431

25-
// reference
32+
33+
/* NOTE: There's another school of thought that subscribes to the opinion that it's redundant to use === when == is
34+
* sufficient. For example, when you use typeof you know it returns a string, so there's no reason to use strict
35+
* equality. However, JSLint requires strict equality; it does make the code look consistent and reduces the mental
36+
* effort when reading code. ("Is this == intentional or an omission?")
37+
*/
38+
39+
40+
// References
2641
// http://net.tutsplus.com/tutorials/javascript-ajax/the-essentials-of-writing-high-quality-javascript/
2742
</script>
2843
</body>

general-patterns/built-in-prototypes.html

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,25 @@
77
<body>
88
<script>
99
/* Title: (Not) Augmenting Built-in Prototypes
10-
Description: only augment built-in prototypes when certain conditions are met
11-
*/
10+
* Description: it can seriously hurt maintainability, because it will make your code less predictable
11+
*/
1212

13+
/* NOTE: You can make an exception of the rule only when all these conditions are met:
14+
15+
* 1. It's expected that future ECMAScript versions or JavaScript implementations will implement this functionality
16+
* as a built-in method consistently. For example, you can add methods described in ECMAScript 5 while waiting for
17+
* the browsers to catch up. In this case you’re just defining the useful methods ahead of time.
18+
* 2. You check if your custom property or method doesn't exist already—maybe already implemented somewhere else in
19+
* the code or already part of the JavaScript engine of one of the browsers you support.
20+
* 3. You clearly document and communicate the change with the team.
21+
*/
1322
if (typeof Object.protoype.myMethod !== "function") {
1423
Object.protoype.myMethod = function () {
1524
// implementation...
1625
};
1726
}
1827

19-
// reference
28+
// References
2029
// http://net.tutsplus.com/tutorials/javascript-ajax/the-essentials-of-writing-high-quality-javascript/
2130
</script>
2231
</body>

general-patterns/conditionals.html

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,32 @@
77
<body>
88
<script>
99
/* Title: Conditionals
10-
Description: pattern and antipattern of using if else
11-
*/
10+
* Description: pattern and antipattern of using if else
11+
*/
1212

13-
// NOTE: Paul Irish states that the first statement is only an antipattern when optimizing for
14-
// low-bandwidth source (such as for a bookmarklet).
15-
// Using the first statement will generally outperform the regex in a loop, and is faster than the
16-
// object literal for lower numbers of conditions (they generally even out around 10 conditions).
17-
// See http://jsperf.com/if-this-or-that
13+
/* NOTE: Paul Irish states that the first statement (normal pattern) is only an antipattern when optimizing for
14+
* low-bandwidth source (such as for a bookmarklet).
15+
* Using the normal pattern will generally outperform the regex (alternative method 1) in a loop,
16+
* and is faster than the object literal (alternative method 2) for lower numbers of conditions,
17+
* they generally even out around 10 conditions.
18+
* See http://jsperf.com/if-this-or-that
19+
*/
1820

19-
// Normal Pattern
21+
// normal pattern
2022
if (type === 'foo' || type === 'bar' ) {}
2123

2224

23-
/* alternative method 1 - regex test */
25+
// alternative method 1 - regex test
2426
if ( /^(foo|bar)$/.test(type) ) {}
2527

2628

27-
/* alternative method 2 - object literal lookup (smaller if < 5 items) */
29+
// alternative method 2 - object literal lookup (smaller if < 5 items)
2830
if ( ({foo:1,bar:1})[type] ) {}
2931

3032

3133
/* alternative method 3 - binary-search-like approach
32-
This approach is best when there are ranges of values for which to test
33-
*/
34-
34+
* This approach is best when there are ranges of values for which to test
35+
*/
3536
if (value == 0){
3637
return result0;
3738
} else if (value == 1){
@@ -94,9 +95,8 @@
9495

9596

9697
/* alternative method 4 - object/array lookup tables
97-
Most useful when there is logical mapping between a single key and a single value
98-
*/
99-
98+
* Most useful when there is logical mapping between a single key and a single value
99+
*/
100100
if (value == 0) {
101101
return result0;
102102
} else if (value == 1) {
@@ -111,7 +111,7 @@
111111
return results[value];
112112

113113

114-
// reference
114+
// References
115115
// http://paulirish.com/2009/perf/
116116
</script>
117117
</body>

general-patterns/for-in-loops.html

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
<body>
88
<script>
99
/* Title: for-in loops
10-
Description: optimized for-in loops
11-
*/
10+
* Description: optimized for-in loops
11+
*/
1212

1313
// the object
1414
var man = {
@@ -23,40 +23,47 @@
2323
Object.prototype.clone = function () {};
2424
}
2525

26-
// 1.
27-
// for-in loop
26+
27+
// antipattern
28+
// for-in loop without checking hasOwnProperty()
29+
for (var i in man) {
30+
console.log(1, ":", man[i]);
31+
}
32+
/*
33+
* result in the console
34+
* hands : 2
35+
* legs : 2
36+
* hands : 1
37+
* clone: function()
38+
*/
39+
40+
41+
// preferred 1
2842
for (var i in man) {
2943
if (man.hasOwnProperty(i)) { // filter
3044
console.log(i, ":", man[i]);
3145
}
3246
}
33-
/*
34-
result in the console
35-
hands : 2
36-
legs : 2
37-
heads : 1
38-
*/
39-
40-
// 2.
41-
// antipattern:
42-
// for-in loop without checking hasOwnProperty()
43-
for (var i in man) {
44-
console.log(1, ":", man[i]);
45-
}
47+
4648
/*
47-
result in the console
48-
hands : 2
49-
legs : 2
50-
hands : 1
51-
clone: function()
52-
*/
49+
* result in the console
50+
* hands : 2
51+
* legs : 2
52+
* heads : 1
53+
*/
5354

55+
56+
// preferred 2
57+
// benefit is you can avoid naming collisions is case the `man` object has redefined `hasOwnProperty`
5458
for (var i in man) {
5559
if (Object.prototype.hasOwnProperty.call(man, i)) { // filter
5660
console.log(i, ":", man[i]);
5761
}
5862
}
5963

64+
65+
// preferred 3
66+
// use a local variable to "cache" `Object.prototype.hasOwnProperty`
6067
var i,
6168
hasOwn = Object.prototype.hasOwnProperty;
6269
for (i in man) {
@@ -65,7 +72,8 @@
6572
}
6673
}
6774

68-
// reference
75+
76+
// References
6977
// http://net.tutsplus.com/tutorials/javascript-ajax/the-essentials-of-writing-high-quality-javascript/
7078
</script>
7179
</body>

general-patterns/for-loops.html

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,57 @@
77
<body>
88
<script>
99
/* Title: for loops
10-
Description: optimized for loops
11-
*/
10+
* Description: optimized for loops
11+
*/
1212

1313
// sub-optimal loop
1414
for (var i = 0; i < myarray.length; i++) {
1515
// do something with myarray[i]
1616
}
1717

18+
// optimization 1 - cache the length of the array with the use of `max`
1819
for (var i = 0, max = myarray.length; i < max; i++) {
1920
// do something with myarray[i]
2021
}
2122

22-
function looper() {
23-
var i = 0,
24-
max,
25-
myarray = [];
26-
27-
// ...
28-
var i, myarray = [];
29-
30-
for (i = 0, max = myarray.length; i < max; i += 1) {
31-
// do something with myarray[i]
32-
}
23+
24+
// optimization 2 - use single var pattern for consistency
25+
// NOTE: A drawback is that it makes it a little harder to copy and paste whole loops while refactoring code.
26+
var i = 0,
27+
max,
28+
myarray = [];
3329

34-
for (i = myarray.length; i--;) {
35-
// do something with myarray[i]
36-
}
30+
for (i = 0, max = myarray.length; i < max; i++) {
31+
// do something with myarray[i]
32+
}
33+
34+
35+
// optimization 3 - substitute `i++` with `i = i + 1` or `i += 1` to avoid excessive trickiness
36+
var i = 0,
37+
max,
38+
myarray = [];
3739

38-
while (i--) {
39-
// do something with myarray[i]
40-
}
41-
40+
for (i = 0, max = myarray.length; i < max; i += 1) {
41+
// do something with myarray[i]
42+
}
43+
44+
45+
// preferred 1
46+
var i, myarray = [];
47+
for (i = myarray.length; i--;) {
48+
// do something with myarray[i]
49+
}
50+
51+
52+
// preferred 2
53+
var myarray = [],
54+
i = myarray.length;
55+
while (i--) {
56+
// do something with myarray[i]
4257
}
4358

44-
// reference
59+
60+
// References
4561
// http://net.tutsplus.com/tutorials/javascript-ajax/the-essentials-of-writing-high-quality-javascript/
4662
</script>
4763
</body>

0 commit comments

Comments
 (0)