6

This is somewhat related to this question, but I'm not asking for resources about best practices in JavaScript, but your actual advise.

I'll start with my own list. You may either post an answer or directly edit the question if you're sure the advise is not controversial.

Here we go:

  • always use var
  • capitalize names of constructor functions - and nothing else
  • use === for comparison
  • use explicit casts for primitives, e.g. Number(), String(), Boolean()
  • check for primitive types with typeof
  • check for object types with instanceof
  • check for built-in object types with Object.prototype.toString() to avoid cross-frame issues, e.g.

    Object.prototype.toString.call(obj) === '[object Array]'
    
  • check this in constructors, e.g.

    function MyObject() {
        if(!(this instanceof arguments.callee))
            throw new Error('constructor called with invalid `this`');
        // [...]
    }
    
  • use anonymous functions for namespacing to not pollute the global scope, e.g.

    (function() {
        var noGlobalVar = 'foo';
        // [...]
    })();
    
  • check hasOwnProperty() in for..in loops - don't assume that no one messed with the prototypes

  • don't use for..in loops to iterate over elements of arrays or array-like objects
Community
  • 1
  • 1
Christoph
  • 164,997
  • 36
  • 182
  • 240

4 Answers4

2

Don't meddle with core types. Never stick something onto Array.prototype -- you don't know who else is doing that, and how such things might interact.

Only check explicit types when it matters. Duck typing is a good concept.

I want to second using anonymous functions to avoid pollution of the global scope. Especially when you work a lot with jQuery, as I do, it's really helpful to use a template like this:

(function($) {
    /* Lots of code */
})(jQuery);
David
  • 3,906
  • 2
  • 23
  • 17
1

This applies to all languages in general:

Avoid deep nesting, it is unacceptable and very hard to read. There are some techniques, for example in loops you can do an early break or continue next iteration instead of wrapping everything inside an if.

ajax333221
  • 11,436
  • 16
  • 61
  • 95
  • 3-4 levels in JS? Sounds like impossible. Sometimes you got 4 levels before you've even started to write something. Consider Object.defineProperties(...) placed in a closure (function () {...}()) - when you start writing your let's say getter it's body is already at level 4. – Szymon Wygnański Feb 28 '13 at 00:55
  • @SzymonWygnański thanks for noting my error, that number was way too low – ajax333221 Feb 28 '13 at 01:26
0

always use jslint.

It's a little bit frustrating at the beginning but it's beneficial.

Jslint will tell you if you break one or more of the "best practices".

Also consider using IDE that supports jslint. I can recommend WebStorm or Sublime Text 2 (these 2 i've tested myself and they support jslint very well).

Szymon Wygnański
  • 10,642
  • 6
  • 31
  • 44
0

use explicit casts for primitives, e.g. Number(), String(), Boolean()

Really? I avoid those like the plague. What's your thinking on that?

Nosredna
  • 83,000
  • 15
  • 95
  • 122
  • 1
    my thinking was to make casts explicit, eg don't do things like `a = 3 + document.forms[0].elemens[0].value`, but `a = 3 + Number(document.forms[0].elemens[0].value)`; notice that I'm **not** advising to use wrapper objects (`new Number()`, `new String()`, ...) – Christoph Feb 01 '09 at 00:08
  • you don't need to do that unless you expect the value to contain a string like 'foo'. which will fail either way. – scunliffe Feb 01 '09 at 00:26
  • @scunliffe: ` 3 + 'foo' === '3foo' `, whereas ` 3 + Number('foo') === NaN ` – Christoph Feb 01 '09 at 00:35
  • Why not use parseInt when you need something to be a number? – AnnanFay Feb 01 '09 at 00:46
  • 1
    @Annan: that was just an example; but you're right, I don't like `parseInt()` because it'll do too much magic: ` parseInt(' 3foo') === 3 `; I believe it's better to validate user input explicitly (e.g. with regular expressions) and use functions which will cleanly fail on invalid input... – Christoph Feb 01 '09 at 00:51