Object Oriented Javascript best practices? [closed] - javascript

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I'm finding myself coding a big project in Javascript. I remember the last one was quite an adventure because hacky JS can quickly becomes unreadable and I want this code to be clean.
Well, I'm using objects to construct a lib, but there are several ways to define things in JS, implying important consequences in the scope, the memory management, the name space, etc. E.G :
using var or not;
defining things in the file, or in a (function(){...})(), jquery style;
using this, or not;
using function myname() or myname = function();
defining methods in the body of the object or using "prototype";
etc.
So what are really the best practices when coding in OO in JS ?
Academic explanations really expected here. Link to books warmly welcome, as long as they deal with quality and robustness.
EDIT :
Got some readings, but I'm still very interested in answers to the questions above and any best practices.

Using `var` or not
You should introduce any variable with the var statement, otherwise it gets to the global scope.
It's worth mentioning that in strict mode ("use strict";) undeclared variable assignments throws ReferenceError.
At present JavaScript does not have a block scope. The Crockford school teaches you to put var statements at the beginning of the function body, while Dojo's Style Guide reads that all variables should be declared in the smallest scope possible. (The let statement and definition introduced in JavaScript 1.7 is not part of the ECMAScript standard.)
It is good practice to bind regularly-used objects' properties to local variables as it is faster than looking up the whole scope chain. (See Optimizing JavaScript for extreme performance and low memory consumption.)
Defining things in the file, or in a `(function(){...})()`
If you don't need to reach your objects outside your code, you can wrap your whole code in a function expression—-it's called the module pattern. It has performance advantages, and also allows your code to be minified and obscured at a high level. You can also ensure it won't pollute the global namespace. Wrapping Functions in JavaScript also allows you to add aspect-oriented behaviour. Ben Cherry has an in-depth article on module pattern.
Using `this` or not
If you use pseudo-classical inheritance in JavaScript, you can hardly avoid using this. It's a matter of taste which inheritance pattern you use. For other cases, check Peter Michaux's article on JavaScript Widgets Without "this".
Using `function myname()` or `myname = function();`
function myname() is a function declaration and myname = function(); is a function expression assigned to variable myname. The latter form indicates that functions are first-class objects, and you can do anything with them, as with a variable. The only difference between them is that all function declarations are hoisted to the top of the scope, which may matter in certain cases. Otherwise they are equal. function foo() is a shorthand form. Further details on hoisting can be found in the JavaScript Scoping and Hoisting article.
Defining methods in the body of the object or using "prototype"
It's up to you. JavaScript has four object-creation patterns: pseudo-classical, prototypical, functional, and parts (Crockford, 2008). Each has its pros and cons, see Crockford in his video talks or get his book The Good Parts as Anon already suggested.
Frameworks
I suggest you pick up some JavaScript frameworks, study their conventions and style, and find those practices and patterns that best fit you. For instance, the Dojo Toolkit provides a robust framework to write object-oriented JavaScript code which even supports multiple inheritance.
Patterns
Lastly, there is a blog dedicated to explore common JavaScript patterns and anti-patterns. Also check out the question Are there any coding standards for JavaScript? in Stack Overflow.

I am going to write down some stuffs that I read or put in application since I asked this question. So people reading it won't get frustrated, as most of the answers are RTMF's in disguise (even if I must admit, suggested books ARE good).
Var usage
Any variable is supposed to be already declared at the higher scope in JS. So when ever you want a new variable, declare it to avoid bad surprises like manipulating a global var without noticing it. Therefore, always use the var keyword.
In an object make, var the variable private. If you want to just declare a public variable, use this.my_var = my_value to do so.
Declaring methods
In JS, they are numerous way of declaring methods. For an OO programmer, the most natural and yet efficient way is to use the following syntax:
Inside the object body
this.methodName = function(param) {
/* bla */
};
There is a drawback: inner functions won't be able to access "this" because of the funny JS scope. Douglas Crockford recommends to bypass this limitation using a conventional local variable named "that". So it becomes
function MyObject() {
var that = this;
this.myMethod = function() {
jQuery.doSomethingCrazy(that.callbackMethod);
};
};
Do not rely on automatic end of line
JS tries to automatically add ; at the end of the line if you forget it. Don't rely on this behavior, as you'll get errors that are a mess to debug.

First ought to read about the prototype-based programming so you know what kind of beast you're dealing with and then take a look at JavaScript style guide at MDC and JavaScript page at MDC. I also find best to force the code quality with a tool, ie. JavaScript Lint or other variants.
Best practices with OO sounds more like you want to find patterns than concentrate on code quality, so look at Google search: javascript patterns and jQuery patterns.
Speed up your JavaScript

You might want to check out Secrets of the JavaScript Ninja by John Resig (jQuery). "This book is intended to take an intermediate JavaScript developer and give him the knowledge he needs to create a cross-browser JavaScript library, from the ground, up."
The draft is available through the publisher:
http://www.manning.com/resig/
Douglas Crockford also has some nice JavaScript articles on his homepage:
http://www.crockford.com/

I often feel like the only guy here who uses MooTools for my javascript.
It stands for My Object Oriented Tools, mootools.
I really like their take on OOP in javascript. You can use their class implementation along with jquery too, so you don't have to ditch jquery (though mootools does it all just as well).
Anyway, give the first link a good read and see what you think, the second link is to the mootools docs.
MooTools & Inheritance
MooTools Classes

Here's a book that covers most of the bases:
Object Oriented Javascript for high quality applicatons and libraries

Related

OOP vs JavaScript

I have a background in OOP. I started to work a lot with JavaScript. As the project grows it's becoming more difficult to maintain it. In Java I apply OOP principles to keep things under control. What should I do with JavaScript, what should I study that is aimed at keeping a JavaScript application under control?
You can apply OOP principles to Javascript development too. Javascript uses prototypal inheritance, but that is an implementation detail. The concepts are still the same. Most of the concepts with which you are familiar have direct analogues in javascript.
Other tried and true methods apply as well:
1) Stay DRY -- Do not Repeat Yourself. Duplicate code is always evil.
2) Separate concerns -- Use the MVC or MVVM patterns to keep code clean and doing only 1 thing.
3) Test -- When I hear "Difficult to maintain" my brain translates that into lack of tests. You can certainly write unit tests for javascript projects.
4) Code Review -- Code reviews can be a good way of rejecting duplicated code, code that is not crafted properly, not formatted, etc....
This is how you define objects and methods in javascript.
function SomeObj() {
this.someMethod = function() {
alert('boo');
}
}
var o_obj = new SomeObj();
o_obj.someMethod(); //alerts "boo"
Hope it helps.
You can also use prototype to create static functions.
this.prototype.someMethod = function() {
alert('boo');
}
When I was in the same situation I started to look at "how other did". Its ended up with http://dojotoolkit.org/ and http://jquery.com and I was looking how they implement widgets/plugins so other could extend the framework.
Another way of defining simple objects and methods in javascript (without the need for new).
function creaeSomeObj() {
var that = {};
that.someMethod = function() {
alert('boo');
}
return that;
}
var o_obj = createSomeObj();
o_obj.someMethod(); //alerts "boo"
This pattern doesn't support inheritance, but many times it is sufficient.
Why "vs"? JavaScript supports object-oriented programming, but not in the traditional class-based way that you see in e.g. Java.
The way JavaScript's OOP works is usually known as "prototypal inheritance", or more specifically "delegative prototypal inheritance". This can be boiled down to "if you're looking for the property 'foo' in an object, and you can't find it there, then try looking for 'foo' inside the object's prototype instead". That is, the lookup of the property is delegated to the object's prototype (we say that the object inherits the properties from the prototype).
The way prototypal inheritance works has a couple of implications. For instance:
Objects in JavaScript are "dynamic" in the sense that they're just a bunch of name-value pairs. New properties can be added and removed during runtime, so they're much less "static" than objects in the typical class sense.
The way delegative prototypal inheritance works ("if you can't find the prototype here, then look here instead") means it's much simpler than classical OOP. From a purely prototypal point of view, you don't need constructors, for example. "Methods" are just regular functions that happen to be attached to the prototype (which means they are available as properties on all inheriting objects).
There are pro's and con's with both prototypal and classical inheritance, but it's important to remember that they're different.
Now, JavaScript is in some senses inspired by Java and other classical languages, so therefore they decided to make the syntax "class-like" to make it easier for people used to classes to get started. I won't elaborate a lot on this; it's documented to a great extent in other places already.
Some interesting posts:
hughfdjackson's introduction to JavaScript OOP -- short and more to-the-point,
Sorella's longer "Understanding Javascript OOP" -- rather in-depth and very complete resource.
Pluralsight has a course on just this topic: Structuring JavaScript Code that may provide some insight. Two caveats: 1. I haven't sat through the course yet - but content looks great and I've been impressed with other Pluralsight courses I've taken, and 2. it is not free (but may be worth the small $ if it saves you time down the road b/c you have better code structure). No, I don't work for Pluralsight.
In addition to the js frameworks mentioned in this thread, can also look at Knockoutjs - great tutorials here learnknockoutjs.com. Knockout is MVVM focused. Note, there is a good discussion in stackoverflow comparing Backbone to Knockout, and Pluralsight also has a course on using Knockout which I have watched and do recommend.
In JavaScript, Functions are Objects; Mozilla Developer Network, McKoss, SitePoint, and JavaScript Kit explain further.
Example JavaScript Object
function myObj() {
this.myMethod = function() {
alert('hello');
}
}
var demo_obj = new myObj();
demo_obj.myMethod();
Patterns to keep things under control
The patterns listed here are particular to JavaScript.
Use a Script Loader.
Use a JS Framework.
Lint your JavaScript. - Tools are availble to run this on your desktop in Rhino or node.
Minify your JS.
The patterns listed here are typical of OOP Languages, and are not
particular to JavaScript.
DRY - Don't Repeat Yourself.
Observer (Pub/Sub) pattern.
Anti-Patterns to let things out of control
Polluting the namespace
use of eval()
Prototyping against the Object object
Inline Script Tags.
use of document.write

Is JavaScript 's “new” Keyword Considered Harmful (Part 2)? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Reading through the following question, I feel the majority of the answers miss the point of why some people (Crockford) choose not to use the "new" keyword. It's not to prevent accidental calling of a function without the "new" keyword.
According to the following article by Crockford regarding prototypal inheritance, he implements an object creation technique that more clearly demonstrates the prototypal nature of JS. This technique is now even implemented in JS 1.8.5.
His argument against using new can be more clearly summed up as:
"This indirection was intended to make the language seem more familiar to classically trained programmers, but failed to do that, as we can see from the very low opinion Java programmers have of JavaScript. JavaScript's constructor pattern did not appeal to the classical crowd. It also obscured JavaScript's true prototypal nature. As a result, there are very few programmers who know how to use the language effectively."
I don't necessarily consider "new" harmful, but I do agree that it does "obscure JavaScript's true prototypal nature," and therefore I do have to agree with Crockford on this point.
What is your opinion of using a "clearer" prototypal object creation technique, over using the "new" keyword?
You right, using new is considered harmful as it doesn't place enough emphasis on OO in JavaScript being prototypical. The main issue is that acts too much like classical classes and one should not think about class. One should think about Object's and creating new Objects with existing objects as blueprints.
new is a remnant of the days where JavaScript accepted a Java like syntax for gaining "popularity".
These days we do Prototypical OO with Object.create and use the ES5 shim.
There is no need for new anymore.
Before the days of ES5 being commonly implemented (only FF3.6 and IE8 are slacking) we used new because we had little choice. someFunction.prototype was the way to do prototypical inheritance.
I recently wrote up a "nice" demonstration of Object.create although I still need to iron out some kinks in the usage. The important thing is to separate Objects from factory functions.
I don't find that new obscures the prototypical nature of the language for me. Granted I've now spent some years getting to know the language well (having made the mistake originally of diving in and starting writing code without a clue how the language actually worked, to my initial cost).
I find new expressive in a way that prefixing "new" on function names or using a helper function, etc., isn't:
var fido = new Dog(); // Simple, clear
var rover = Dog(); // Very unclear (fortunately people mostly don't do this, but I've seen it)
var scruffles = newDog(); // Clearer, but hacky
var fifi = Object.create(Dog); // (Crockford) Verbose, awkward, not esp. clear
Whether it's prototypical or class-based (and most of that doesn't relate to the new keyword at all), I still think best in terms of functionality grouped together into building blocks (objects or classes or whatever) and then specific objects I can muck about without affecting those building blocks. For me, new as a means of clearly identifying my intent is neither classy or prototypical, it's just clear.
For me, new is just as vital a part of JavaScript as prototypes themselves are, as the wonderfully dexterous functions are. The is is no conflict.
And speaking practically, there are a lot more programmers out there used to using new to create new instances of things than not, and it's a widespread practice in the JavaScript community despite Crockford's efforts (don't misunderstand, I have a lot of respect for Crockford). If I'm staffing up a project, I don't want the retraining hassles.
This is not to say that the way that you define hierarchies of prototypical objects in JavaScript is a thing of beauty and a joy forever. It's a royal pain, especially without the ECMAScript5 enhancements. But define a helper function to help you wire up your hierarchies (whatever you want to call them), and you're done. (See update below.)
[And yes, the whole thing about constructor functions being called without new really is a red herring (you did say you didn't think it was a main point either). You almost never see it happen in the real world. Actually, some of what JavaScript does with that is quite nice (the way String and Number cast, for instance); other parts (what Date does **shudder**) are not so nice...]
As of ES2015 (ES6), creating hierarchies of prototypes and constructors is a breeze, thanks to the new class syntax. No need for helpers anymore.
class Base {
constructor(name) {
this.name = name;
}
greeting() {
return "Hi, I'm " + this.name;
}
}
class Derived extends Base {
constructor(name, age) {
super(name);
this.age = age;
}
greeting() {
return super.greeting() + " and I'm " + this.age + " years old";
}
}
That doesn't mean we want them for everything, of course. I use Object.create to great effect when I need to extend a single object.
My biggest problem with new is that it violates the Open/Closed principle. Because of the way that new manipulates the value of this, constructors are closed for extension, which means if you need to extend it, you must modify it, possibly breaking callers in the process.
Some examples of how factories can be extended that new doesn't allow:
Hide the details of object creation. (The rest of these are examples of why you might want to do that)
Store mutable prototypes and init functions on the factory object, accessible with this. (With new, this always refers to the newly created object).
Extend the pool of possible object types by allowing you to add capabilities to the factory object (extensible polymorphism).
Redefine the meaning of this during instantiation with .call() or .apply() (extending code-reuse).
Return a proxy to a new object in another memory space (iframe, window, different machine).
Conditionally return a reference to an existing object (Actually, you can do that with new and constructors, but then this is meaningless and misleading inside the constructor because a new instance gets allocated and then thrown away if you return something other than a new object).
Enable changes to instantiation strategy without breaking callers.
Note: I'm constantly irritated that I can't easily use any of these strategies with Backbone.js because it forces you to use new, unless you wrap it, but then you close off its standard inheritance mechanism. By way of contrast, I have never found myself irritated that jQuery uses a factory function to instantiate jQuery-wrapped DOM collections.

anonymous functions considered harmful? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
The more I delve into javascript, the more I think about the consequences of certain design decisions and encouraged practices. In this case, I am observing anonymous functions, a feature which is not only JavaScript-provided, but I see strongly used.
I think we can all agree on the following facts:
the human mind does not deal with more than 7 plus minus two entities (Miller's law)
deep indentation is considered bad programming practice, and generally points out at design issues if you indent more than three or four levels. This extends to nested entities, and it's well presented in the python Zen entry "Flat is better than nested."
the idea of having a function name is both for reference, and for easy documentation of the task it performs. We know, or can expect, what a function called removeListEntry() does. Self-documenting, clear code is important for debugging and readability.
While anonymous functions appears to be a very nice feature, its use leads to deeply nested code design. The code is quick to write, but difficult to read. Instead of being forced to invent a named context for a functionality, and flatten your hierarchy of callable objects, it encourages a "go deep one level", pushing your brain stack and quickly overflowing the 7 +/- 2 rule. A similar concept is expressed in Alan Cooper's "About Face", quoting loosely "people don't understand hierarchies". As programmers we do understand hierarchies, but our biology still limits our grasping of deep nesting.
I'd like to hear you on this point. Should anonymous functions be considered harmful, an apparent shiny syntactic sugar which we find later on to be salt, or even rat poison ?
CW as there's no correct answer.
As I see it, the problem you're facing is not anonymous functions, rather an unwillingness to factor out functionality into useful and reusable units. Which is interesting, because it's easier to reuse functionality in languages with first-class functions (and, necessarily, anonymous functions) than in languages without.
If you see a lot of deeply nested anonymous functions in your code, I would suggest that there may be a lot of common functionality that can be factored out into named higher-order functions (i.e. functions that take or return ("build") other functions). Even "simple" transformations of existing functions should be given names if they are used often. This is just the DRY principle.
Anonymous functions are more useful functionally than they are harmful legibly. I think that if you format your code well enough, you shouldn't have a problem. I don't have a problem with it, and I'm sure I can't handle 7 elements, let alone 7 + 2 :)
Actually, hierarchies help to overcome 7+/-2 rule the same way as OOP does. When you're writing or reading a class, you read its content and nothing of outside code so you are dealing with relatively small portion of entities. When you're looking at class hierarchies, you don't look inside them, meaning then again you are dealing with small number of entities.
The same if true for nested functions. By dividing your code into multiple levels of hierarchy, you keep each level small enough for human brain to comprehend.
Closures (or anonymous functions) just help to break your code into slightly different way than OOP does but they doesn't really create any hierarchies. They are here to help you to execute your code in context of other block of code. In C++ or Java you have to create a class for that, in JavaScript function is enough. Granted, standalone class is easier to understand as it is just easier for human to look at it as at standalone block. Function seems to be much smaller in size and brain sometimes think it can comprehend it AND code around it at the same time which is usually a bad idea. But you can train your brain not to do that :)
So no, I don't think anonymous functions are at all harmful, you just have to learn to deal with them, as you learnt to deal with classes.
Amusingly, JavaScript will let you name "anonymous" functions:
function f(x) {
return function add(y) {
return x+y;
};
}
I think closures have enormous benefits which should not be overlooked. For example, Apple leverages "blocks"(closures for C) with GCD to provide really easy multithreading - you don't need to setup context structs, and can just reference variables by name since they're in scope.
I think a bigger problem with Javascript is that it doesn't have block scope(blocks in this case referring to code in braces, like an if statement). This can lead to enormous complications, forcing programmers to use unnecessary closures to get around this Javascript design limitation.
I also think anonymous functions (in latest languages often referred as closures) have great benefits and make code often more readable and shorter. I sometimes am getting really nuts when I have to work with Java (where closures aren't first class language features).
If indentation and too many encapsulated function-variables are the problem then you should refactor the code to have it more modular and readable.
Regarding java-script I think that function-variables look quite ugly and make code cluttered (the encapsulated function(...){} string makes java-script code often less readable). As an example I much prefer the closure syntax of groovy ('{}' and '->' chars).
If a function is not understandable without a name, the name is probably too long.
Use comments to explain cryptic code, don't rely on names.
Who ever came up with the idea of requiring functions to be bound to identifiers did every programmer a disservice. If you've never done functional programming and you're not familiar with and comfortable with functions being first-class values, you're not a real programmer.
In fact, to counter your own argument, I would go so far as to consider functions bound to (global) names to be harmful! Check Crockford's article about private and public members and learn more.

What lessons can be learned from the prototype model in javascript?

The question is from a language design perspective.
I should explain a little about the situation. I am working on a javascript variant which does not support prototypes, however it is overdue a decent type system (most importantly support for instanceof). The ecmascript spec is not important, so i have the freedom to implement something different and better suited.
In the variant:-
You do not declare constructors with function foo(), rather constructors are declared in template files, which means constructors exist in a namespace (detirmined by the path of the file)
Currently all inheritance of behaviour is done by applying templates which means all shared functions are copied to each individual object (there are no prototypes afterall).
Never having been a web developer, this puts me in the slightly bizarre position of never having used prototypes in anger. Though this hasn't stopped me having opinions on them.
My principal issues with the prototype model as i understand it are
unnecessary littering of object namespace, obj.prototype, obj.constructor (is this an immature objection, trying to retain ability to treat objects as maps, which perhaps they are not?)
ability to change shared behaviour at runtime seems unnecessary, when directly using an extra level of indirection would be more straight forward obj.shared.foo(). Particularly it is quite a big implementation headache
people do not seem to understand prototypes very well generally e.g. the distinction between a prototype and a constructor.
So to get around these my idea is to have a special operator constructorsof. Basically the principal is that each object has a list of constructors, which occasionally you will want access to.
var x = new com.acme.X();
com.acme.Y(x,[]); // apply y
(constructorsof x) // [com.acme.Y,com.acme.X,Object];
x instanceof com.acme.X; // true
x instanceof com.acme.Y; // true
All feedback appreciated, I appreciate it maybe difficult to appreciate my POV as there is a lot i am trying to convey, but its an important decision and an expert opinion could be invaluable.
anything that can improve my understanding of the prototype model, the good and the bad.
thoughts on my proposal
thanks,
mike
edit: proposal hopefully makes sense now.
Steve Yegge has written a good technical article about the prototype model.
I don't think your issues with the prototype model are valid:
unnecessary littering of object namespace, obj.prototype, obj.constructor
prototype is a property of the contructor function, not the object instance. Also, the problem isn't as bad as it sounds because of the [[DontEnum]] attribute, which unfortunately can't be set programatically. Some of the perceived problems would go away if you could.
is this an immature objection, trying to retain ability to treat objects as maps, which perhaps they are not?
There's no problem with using objects as maps as long as the keys are strings and you check hasOwnProperty().
ability to change shared behaviour at runtime seems unnecessary, when directly using an extra level of indirection would be more straight forward obj.shared.foo(). Particularly it is quite a big implementation headache
I don't see where the big implementation headache in implementning the prototype chain lies. In fact, I consider prototypical inheritance conceptually simpler than class-based inheritance, which doesn't offer any benefits in languages with late-binding.
people do not seem to understand prototypes very well generally e.g. the distinction between a prototype and a constructor.
People who only know class-based oo languages like Java and C++ don't understand JavaScript's inheritance system, news at 11.
In addition to MarkusQ's suggestions, you might also want to check out Io.
It might just be easier to try a few things with practical code. Create the language with one simple syntax, whatever that is, and implement something in that language. Then, after a few iterations of refactoring, identify the features that are obstacles to reading and writing the code. Add, alter or remove what you need to improve the language. Do this a few times.
Be sure your test-code really exercises all parts of your language, even with some bits that really try to break it. Try to do everything wrong in your tests (as well as everything right)
Reading up on "self", the language that pioneered the prototype model, will probably help you more than just thinking of it in terms of javascript (especially since you seem to associate that, as many do, with "web programming"). A few links to get you started:
http://selflanguage.org/
http://www.self-support.com/
Remember, those who fail to learn history are doomed to reimplement it.

What anti-patterns exist for JavaScript? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I find that what not to do is a harder lesson to learn than what should be done.
From my experience, what separates an expert from an intermediate is the ability to select from among various seemingly equivalent ways of doing the same thing.
So, when it comes to JavaScript what kinds of things should you not do and why?
I'm able to find lots of these for Java, but since JavaScript's typical context (in a browser) is very different from Java's I'm curious to see what comes out.
Language:
Namespace polluting by creating a large footprint of variables in the global context.
Binding event handlers in the form 'foo.onclick = myFunc' (inextensible, should be using attachEvent/addEventListener).
Using eval in almost any non-JSON context
Almost every use of document.write (use the DOM methods like document.createElement)
Prototyping against the Object object (BOOM!)
A small one this, but doing large numbers of string concats with '+' (creating an array and joining it is much more efficient)
Referring to the non-existent undefined constant
Design/Deployment:
(Generally) not providing noscript support.
Not packaging your code into a single resource
Putting inline (i.e. body) scripts near the top of the body (they block loading)
Ajax specific:
not indicating the start, end, or error of a request to the user
polling
passing and parsing XML instead of JSON or HTML (where appropriate)
Many of these were sourced from the book Learning JavaScript Design by Addy Osmati: https://www.oreilly.com/library/view/learning-javascript-design/9781449334840/ch06.html
edit: I keep thinking of more!
Besides those already mentioned...
Using the for..in construct to iterate over arrays
(iterates over array methods AND indices)
Using Javascript inline like <body onload="doThis();">
(inflexible and prevents multiple event listeners)
Using the 'Function()' constructor
(bad for the same reasons eval() is bad)
Passing strings instead of functions to setTimeout or setInterval
(also uses eval() internally)
Relying on implicit statements by not using semicolons
(bad habit to pick up, and can lead to unexpected behavior)
Using /* .. */ to block out lines of code
(can interfere with regex literals, e.g.: /* /.*/ */)
<evangelism>
And of course, not using Prototype ;)
</evangelism>
The biggest for me is not understanding the JavaScript programming language itself.
Overusing object hierarchies and building very deep inheritance chains. Shallow hierarchies work fine in most cases in JS.
Not understanding prototype based object orientation, and instead building huge amounts of scaffolding to make JS behave like traditional OO languages.
Unnecessarily using OO paradigms when procedural / functional programming could be more concise and efficient.
Then there are those for the browser runtime:
Not using good established event patterns like event delegation or the observer pattern (pub/sub) to optimize event handling.
Making frequent DOM updates (like .appendChild in a loop), when the DOM nodes can be in memory and appended in one go. (HUGE performance benefit).
Overusing libraries for selecting nodes with complex selectors when native methods can be used (getElementById, getElementByTagName, etc.). This is becoming lesser of an issue these days, but it's worth mentioning.
Extending DOM objects when you expect third-party scripts to be on the same page as yours (you will end up clobbering each other's code).
And finally the deployment issues.
Not minifying your files.
Web-server configs - not gzipping your files, not caching them sensibly.
<plug> I've got some client-side optimization tips which cover some of the things I've mentioned above, and more, on my blog.</plug>
browser detection (instead of testing whether the specific methods/fields you want to use exist)
using alert() in most cases
see also Crockford's "Javascript: The Good Parts" for various other things to avoid. (edit: warning, he's a bit strict in some of his suggestions like the use of "===" over "==" so take them with whatever grain of salt works for you)
A few things right on top of my head. I'll edit this list when I think of more.
Don't pollute global namespace. Organize things in objects instead;
Don't omit 'var' for variables. That pollutes global namespace and might get you in trouble with other such scripts.
any use of 'with'
with (document.forms["mainForm"].elements) {
input1.value = "junk";
input2.value = "junk";
}
any reference to
document.all
in your code, unless it is within special code, just for IE to overcome an IE bug. (cough document.getElementById() cough)
Bad use of brace positioning when creating statements
You should always put a brace after the statement due to automatic semicolon insertion.
For example this:
function()
{
return
{
price: 10
}
}
differs greatly from this:
function(){
return{
price: 10
}
}
Becuase in the first example, javascript will insert a semicolon for you actually leaving you with this:
function()
{
return; // oh dear!
{
price: 10
}
}
Using setInterval for potentially long running tasks.
You should use setTimeout rather than setInterval for occasions where you need to do something repeatedly.
If you use setInterval, but the function that is executed in the timer is not finished by the time the timer next ticks, this is bad. Instead use the following pattern using setTimeout
function doThisManyTimes(){
alert("It's happening again!");
}
(function repeat(){
doThisManyTimes();
setTimeout(repeat, 500);
})();
This is explained very well by Paul Irish on his 10 things I learned from the jQuery source video
Not using a community based framework to do repetitive tasks like DOM manipulation, event handling, etc.
Effective caching is seldomly done:
Don't store a copy of the library (jQuery, Prototype, Dojo) on your server when you can use a shared API like Google's Libraries API to speed up page loads
Combine and minify all your script that you can into one
Use mod_expires to give all your scripts infinite cache lifetime (never redownload)
Version your javascript filenames so that a new update will be taken by clients without need to reload/restart
(i.e. myFile_r231.js, or myFile.js?r=231)

Categories