Skip to content

Commit 476c358

Browse files
committed
Merge pull request #1 from shichuan/master
Merge
2 parents 35d8f10 + adb7570 commit 476c358

14 files changed

Lines changed: 436 additions & 24 deletions

function-patterns/currying.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
};
2020

2121
// invoke a function
22-
sayHi(); // "Hello"
22+
sayHi(); // "Hello!"
2323
sayHi('world'); // "Hello, world!"
2424

2525
// apply a function
@@ -175,4 +175,4 @@
175175
*/
176176
</script>
177177
</body>
178-
</html>
178+
</html>

function-patterns/init-time-branching.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
utils.addListener = function (el, type, fn) {
3737
el.addEventListener(type, fn, false);
3838
};
39+
utils.removeListener = function(el, type, fn) {
40+
el.removeEventListener(type, fn, false);
41+
};
3942
} else if (typeof document.attachEvent !== 'undefined') { // IE
4043
utils.addListener = function (el, type, fn) {
4144
el.attachEvent('on' + type, fn);
@@ -57,4 +60,4 @@
5760
// http://shop.oreilly.com/product/9780596806767.do?sortby=publicationDate
5861
</script>
5962
</body>
60-
</html>
63+
</html>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<title>JavaScript Patterns</title>
5+
<meta charset="utf-8">
6+
</head>
7+
<body>
8+
<script>
9+
/* Title: Partial application
10+
Description: the process of fixing a number of arguments to a function, producing another function of smaller arity
11+
*/
12+
13+
var partialAny = (function(aps){
14+
15+
// This function will be returned as a result of the immediately
16+
// invoked function expression and assigned to the `partialAny` var.
17+
function func(fn){
18+
var argsOrig = aps.call(arguments, 1);
19+
return function() {
20+
var args = [],
21+
argsPartial = aps.call(arguments),
22+
i = 0;
23+
// Iterate over all the originally-spedicified arguments. If that
24+
// argument was the `partialAny._` placeholder, use the next just
25+
// passed-in argument, otherwise use the originally-specified
26+
// argument.
27+
for ( ; i < argsOrig.length; i++ ) {
28+
args[i] = argsOrig[i] === func._
29+
? argsPartial.shift()
30+
: argsOrig[i];
31+
}
32+
33+
// If any just-passed-in arguments remain, add them to the end.
34+
return fn.apply( this, args.concat( argsPartial ));
35+
};
36+
}
37+
38+
// This is used as the placeholder argument.
39+
func._ = {};
40+
41+
return func;
42+
})(Array.prototype.slice);
43+
44+
// Slightly more legitimate example
45+
46+
function hex( r, g, b ) {
47+
return '#' + r + g + b;
48+
}
49+
50+
var redMax = partialAny( hex, 'ff', partialAny._, partialAny._);
51+
console.log(redMax('11','22')); // "#ff1122"
52+
53+
// Because `_` is easier on the eyes than `partialAny._`, let's use
54+
// that instead. This is, of course, entirely optional, and the name
55+
// could just as well be `foo` or `PLACEHOLDER` instead of `_`.
56+
57+
var __ = partialAny._;
58+
59+
var greenMax = partialAny( hex, __, 'ff' );
60+
console.log(greenMax( '33', '44' ));
61+
62+
var blueMax = partialAny( hex, __, __, 'ff' );
63+
console.log(blueMax( '55', '66' ));
64+
65+
var magentaMax = partialAny( hex, 'ff', __, 'ff' );
66+
console.log(magentaMax( '77' ));
67+
68+
// reference
69+
// http://msdn.microsoft.com/en-us/magazine/gg575560.aspx
70+
</script>
71+
</body>
72+
</html>

function-patterns/returning-functions.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@
2020
var my = setup(); // alerts 1
2121
my(); // alerts 2
2222

23-
var setup = function (count) {
23+
24+
25+
// Your setup function can store some private data in a closure and use that data somehow.
26+
// Here setup() creates a counter function, which gives a next ID for example. But the count variable is not exposed.
27+
28+
var setup = function () {
2429
var count = 0;
2530
return function () {
26-
return (count += 1);
31+
return ++count;
2732
};
2833
};
2934
// usage
@@ -33,8 +38,7 @@
3338
//next(); // returns 3
3439

3540
// reference
36-
// http://www.jspatterns.com/
37-
// http://shop.oreilly.com/product/9780596806767.do?sortby=publicationDate
41+
// http://www.jspatterns.com/returning-functions/
3842
</script>
3943
</body>
4044
</html>

general-patterns/conditionals.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@
130130
console.log(result); //3
131131
type == 'foo' && type2 == 'bar' && result == 3 && (result=0); //parentheses avoid "invalid assignment left-hand side" error
132132
console.log(result); //0
133-
type == 'OOF' || result++; //equivalent: type != 'OFF' && result++;
133+
type == 'OOF' || result++; //equivalent: type != 'OOF' && result++;
134134
console.log(result); //1
135135

136136

general-patterns/function-declarations.html

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,25 @@
3030
* 1. Provides the debugger with an explicit function name: helps stack inspection.
3131
* 2. Allows recursive functions: getData can call itself.
3232
* Issues:
33-
* 1. there are historic quirks with IE
33+
* 1. Can break IE, coffeescript doesn't do function names:
34+
* https://github.com/jashkenas/coffee-script/issues/366
3435
*/
3536
var getData = function getData () {
3637
};
3738

39+
// named function expression + 'F'
40+
/* Benefits:
41+
* 1. Get's rid of (anonymous funciton) in stack traces
42+
* 2. Recurse by calling the name + 'F'
43+
* 3. Doesn't break an IE (well, unless there's a function name collision of the sort described here: https://github.com/jashkenas/coffee-script/issues/366#issuecomment-242134)
44+
*/
45+
var getData = function getDataF () {
46+
};
47+
3848

3949
// References
4050
// http://ejohn.org/blog/javascript-as-a-first-language/
4151
// http://kangax.github.com/nfe/
4252
</script>
4353
</body>
44-
</html>
54+
</html>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<title>JavaScript Patterns</title>
5+
<meta charset="utf-8">
6+
</head>
7+
<body>
8+
<script>
9+
/* Title: Shim Sniffing
10+
* Description:
11+
*/
12+
13+
// antipattern
14+
Array.prototype.map = function() {
15+
// stuff
16+
};
17+
18+
// better
19+
if (!Array.prototype.map) {
20+
Array.prototype.map = function() {
21+
// stuff
22+
};
23+
}
24+
25+
// even better
26+
if (typeof Array.prototype.map !== "function") {
27+
Array.prototype.map = function() {
28+
// stuff
29+
}
30+
}
31+
32+
33+
// If use either native or your own implementation, but not others:
34+
// When you call toString() of a native function it should return a string with a function that has a body of [native code]
35+
36+
// by default there is white spaces and new lines issue
37+
console.log(Array.prototype.map.toString().replace(/\s/g, '*'));
38+
// "*function*map()*{*****[native*code]*}*" // IE
39+
// "function*map()*{*****[native*code]*}" // FF
40+
// "function*map()*{*[native*code]*}" // Chrome
41+
42+
// a proper check can fix the problem
43+
console.log(Array.prototype.map.toString().replace(/\s/g, ''));
44+
// "functionmap(){[nativecode]}"
45+
46+
// a reusable shim() function
47+
function shim(o, prop, fn) {
48+
var nbody = "function" + prop + "(){nativecode]}";
49+
if (o.hasOwnProperty(prop) &&
50+
o[prop].toString().replace(/\s/g, '') === nbody) {
51+
// native!
52+
return true;
53+
}
54+
// shim
55+
o[prop] = fn;
56+
}
57+
58+
// this is native, cool
59+
shim(
60+
Array.prototype, 'map',
61+
function(){/*...*/}
62+
); // true
63+
64+
// this is new
65+
shim(
66+
Array.prototype, 'mapzer',
67+
function(){console.log(this)}
68+
);
69+
70+
[1,2,3].mapzer(); // alerts 1,2,3
71+
72+
// References
73+
// http://www.jspatterns.com/shim-sniffing/
74+
</script>
75+
</body>
76+
</html>

general-patterns/switch-pattern.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
* 4. Avoiding fall-throughs (when you omit the break intentionally). If you're absolutely convinced
1818
* that a fall-through is the best approach, make sure you document such cases, because they might
1919
* look like errors to the readers of your code.
20-
* 5. Ending the `switch` with a `default`: to make sure there's always a sane result even if none of the cases matched.
20+
* 5. Ending the `switch` with a `default`: to make sure there's always a sane result even if none of
21+
* the cases matched.
2122
*/
2223

2324
var inspect_me = 0,

jquery-patterns/cache-selector.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717

1818

1919
// preferred
20-
var photo = $('.photo');
20+
var photo;
2121
$('.list-item').click(function () {
22+
photo = photo || $('.photo');
2223
photo.hide();
2324
});
2425

jquery-patterns/context-and-find.html

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,17 @@
77
<body>
88
<script>
99
/* Title: context and find
10-
* Description: better to choose `find` over `context`
10+
* Description: better to choose `find` over `context`
1111
*/
1212

13-
// antipattern 1
13+
1414
var arms = $('div.robotarm', '#container');
15-
16-
17-
// preferred 1
18-
var arms = $('#container').find('div.robotarm');
19-
20-
21-
// antipattern 2
2215
$('.reply_form', $(this).closest('.comment')).hide();
2316

24-
25-
// preferred 2
17+
// no performance gain over doing this, but a preferred pattern for readability reason
18+
var arms = $('#container').find('div.robotarm');
2619
$(this).closest('.comment').find('.reply_form').hide();
27-
20+
2821

2922
// References
3023
// http://paulirish.com/2009/perf/

0 commit comments

Comments
 (0)