Some have commented that the linked article may not always contain best practices. The following links always seem to get fantastic praise - they're permanently in my JS bookmarks. Having an understanding of the core language rather than using frameworks is a great start; these articles will certainly help.
I'm going to be critical and say that I don't like the format of this reference; each entry in the table of contents links to a source file in github (opening in a new window/tab) instead of being, for example, a collapsed code box in the same tab.
Second, they're not .js files, but .html files with (in my opinion) obsolete / unnecessary html boilerplate surrounding it. If it's simply a page to demonstrate / display JS patterns, they should be plain .js files, I think; from what I've seen, those should run equally well in a browser and node.js.
I'm also not a fan of tab-based indentation, the examples could be a lot more compact (and readable) horizontally if using two-space indentation instead of tabs.
>I'm also not a fan of tab-based indentation, the examples could be a lot more compact (and readable) horizontally if using two-space indentation instead of tabs.
That's the forte of using tabs. Change your display width of tabs to 2 spaces instead of 4.
I'm not sure about this. The very first link I clicked had some iffy advice.
The "Function declaration" section makes an unsubstantiated claim that function declarations are an antipattern, neglecting to mention the significant difference in effect between a declaration and a function expression assigned to a variable. Declarations are subject to function hoisting; IIFEs and expressions assigned to variables aren't. (But the variables themselves are, which is further confusing.) In other words:
fnDeclaration(); // This function is ready for use.
function fnDeclaration() {
console.log('This function is ready for use.');
}
// - but -
fnExpression(); // TypeError: undefined is not a function.
typeof fnExpression; // 'undefined'
var fnExpression = function() {
console.log('This function is ready for use.');
};
fnExpression(); // This function is ready for use.
typeof fnExpression; // 'function'
Named function expressions are neat, I guess, but the trailing F looks more like an odd, Hungarian stylistic choice than a fix for a serious issue in IE<8. Given that the author(s) either didn't know or just forgot to mention (at first) the IE problems you could meet with if you followed this advice, I'm a little bit concerned about this reference.
Personally, I prefer function declaration for most functions (unless they are bound dynamically). The reason is very simple: the "function" keyword at the beginning of the line makes it very clear and obvious what's going on. I prefer the code to be its own documentation.
Also, aside from hoisting, there is a much better solution for named+assigned function declarations, because the reason for naming such a function is to use it recursively. Hence, just use the verb form of the word "recurse" and it immediately self-documents that the function is recursive:
var fibs = function recurse(n, curr, last) {
curr = curr || 1;
last = last || 0;
return n <= 0 ? last : recurse(n - 1, curr + last, curr);
};
The comma operator takes two expressions, evaluates them both, and returns the second. In this case, (1, eval) becomes a reference to the eval function and then gets fed 'this'. Since the call is now indirect, the eval happens in the global scope where 'this' is guaranteed to be the global object.
The right side is needed for ES5 strict mode, where `this` does not become the global object in a function that wasn't called with `new`, call(), or apply(). In that case the left side will be something falsy and the right side will take over. Details here: http://tinyurl.com/cwbxvxh
I'm not sure if there's some broken javascript on my browser, but the big blue navigation box sits right on top of the content, making about half the text unreadable!
Thanks for the list, looks like I have some reading to do...
One thing I was hoping to see was some good AJAX patterns, not just saying oh well that's pattern X, but actual examples. I found this link, but sadly they never finished the following parts of the article: enterprisejquery.com/2010/07/enterprise-ajax-patterns-part-1-from-enterprise-beginnings/
What's the best pattern to use for a rails app? I've been name-spacing my js so that objects get instantiated based on controller/action using the Garber-Irish Technique. I've found this a great technique, however, I still need a way to organize my js objects into modules/submodules for example. have anyone looked into this?
// optimization 1 - cache the length of the array with the use of `max`
for (var i = 0, max = myarray.length; i < max; i++) {
// do something with myarray[i]
}
The code is OK, but 'max' is a very poor name. It sounds too much like Math.max, and it isn't the maximum value for the loop. It's one greater than that.
If you want to cache the array length like this, then any of these names would be far better than max: either 'length' to match the 'array.length', or 'len' for something shorter, or 'n' if you want it really short. These names all better reflect the meaning of this variable: the length of the array. ('n' stands for 'number', as in the number of elements in the array.)
Later on the page it recommends:
// preferred 1
var i, myarray = [];
for (i = myarray.length; i--;) {
// do something with myarray[i]
}
I'm not a fan of running loops backwards for optimization except where it's really necessary. When I'm reading the code I rarely know whether the backwards loop is simply an optimization, or essential to the algorithm. It adds mystery to the code, and I don't like that.
Of course a comment could be added saying "Backwards loop is for optimization only" or "Backwards loop is needed for the algorithm", but I've never seen a backwards loop aficionado do this.
A few years ago I worked with someone who hated jQuery and libraries in general and preferred to write his own bare metal DOM loops for everything. And he wrote them all backwards. Later on he warmed up a bit to the idea of using jQuery, after seeing a 20-line bare metal function be reduced to a simple and straightforward selector, but when we started going through the code it was never clear if we needed to add a ":last" to the selector to make it match the backwards loop or not.
It's pretty rare that this kind of loop optimization will make much difference, unless the work done in the loop body is truly minimal.
// somewhere else in the code
// a method was added to all objects
if (typeof Object.prototype.clone === 'undefined') {
Object.prototype.clone = function () {
};
}
Now this is part of a discussion about why you should use 'hasOwnProperty()' in a for-in loop to avoid enumerating Object.prototype additions, but there should also be a mention that you should not extend Object.prototype at all, ever, unless you are 100% certain that all the code in your page or project is under your own control and carefully uses hasOwnProperty().
For example, the Google Maps API has for-in loops that do not use hasOwnProperty(). If you extend Object.prototype, then no matter how careful you are in the rest of your own code, you'll have some confusing problems if you later want to add a Google map to your page.
(At least the Maps API used to work this way - it's possible that they have started using hasOwnProperty() now - I haven't checked it in a while. But the same problem could occur with any third-party code you may want to use.)
switch (inspect_me) {
case 0:
result = "zero";
break;
case 1:
result = "one";
break;
default:
result = "unknown";
}
Omitting the break; on the last case in a switch statement is a bad idea. It's too easy to add another case below that and forget the break statement. Better to use break on every case even if it is redundant at the end.
I clicked on the Builder Pattern , it linked to a file but it would be more interesting to have a bit of an explanation. That why UML diagrams are usefull. right now https://github.com/shichuan/javascript-patterns/blob/master/... is hard to understand. I would propose a simple exemple for the builder pattern .
let's say we have an array of datas : [0,10,200,50] and we want a representation of the data.
So the director would use different builders to represent these datas ( a bar chart , a line chart , etc ...).
What i find important with design patterns and often lacking in books is real use cases.You often get strange exemples that , may be interesting but you actually can use them in a real application. Usually the builder ,the fly-weight and the chain of reponsability are often explained badly or with horrible exemples.
I dream of a book that does 2 things :
- explain each pattern with real exemples and propose a list of real uses cases where the pattern would be usefull
- has an extended tutorial at the end of the book the makes the user actually build a full application with all the patterns studied. For instance , a drawing application with different shapes, pens , filters , commands , menus , undo , redo , data serialization , that would use all the main design patterns and make them work together.
If such a book exists ( in java , as3 , C# , javascript ,... (just not in C++ or smalltalk ;) ) ) , i would be interested to know about it.
Now javascript has some patterns of its own ( module pattern , etc ... ) that's interesting to know them too.
Eloquent JavaScript: http://eloquentjavascript.net/contents.html
Learning JavaScript Design Patterns: http://addyosmani.com/resources/essentialjsdesignpatterns/bo...
JS The Right Way: http://jstherightway.com/
Learning Advanced JavaScript: http://ejohn.org/apps/learn/
Ask HN: JavaScript Dev Tools: http://news.ycombinator.com/item?id=3550998
MVC Architecture for JS: http://michaux.ca/articles/mvc-architecture-for-javascript-a...
Large-Scale JS Application Architecture: http://addyosmani.com/largescalejavascript/
Mozilla Developer Network - Intro to OO JS: https://developer.mozilla.org/en-US/docs/JavaScript/Introduc...