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.
Related
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 9 years ago.
Improve this question
I'm interested in how you guys lay out your Javascript objects/classes when they contain lots of functions, all of which need to be on the same 'level' (i.e. they need to remain as first level functions of the object).
So with a structure like this...
Namespace.class = {
abc: 1,
def: 2,
ghi: 3,
funcA: function(){
// Some logic
},
funcB: function(){
// Some logic
},
// Lots more functions
funcN: function(){
// Some logic
}
}
This can all get pretty unwieldy. How do you lay out these types of objects to make them readable, easy to maintain and quick for new developers to pick up?
My approach has been to organise everything in alphabetical order, so you know roughly where to go if you know a function's name.
But does it make more sense to group functions that are closely related in what they do and those that refer to eachother?
There are many approaches here and it depends on how exactly you interact with your code.
Some things to keep in mind:
1) If the code is unwieldy, a refactoring is probably overdue.
Consider breaking your class into smaller classes each dealing with different aspects of what the big class does. Split functionality in multiple namespaces if you use static functions rather than classes.
Consider splitting functionality over multiple files (one-class-per-file for example) and having a build process that combines and minifies your output.
2) Tools can help.
If you deal with large codebases it's probably a good idea to find an editor (or learn to use its functions better) that can help you deal with it. Your IDE will probably have some functionality to help you navigate the file structure better, like a file structure overview, or code regions, or objects view
3) Organize functions by what makes sense.
An alphabetic solution could make sense in some situations, but grouping by functionality is probably better. Putting exported methods all in one place is probably a good idea as well:
Namespace = function() {
var f1 = function() { };
var f2 = function() { }; // this is internal
// Exported methods
return {
f1 : f1
}
}();
4) Document your code.
While reading the code is invaluable in giving someone an in-depth understanding, code ducmentation is essential in having a first-glance understanding. It can also be useful to you during development because you don't have to remember all the quirks of your code.
5) Enforce a coding style that can help you.
Your coding style can help you find things in the code easier. If you always use the same spacing, put braces the same way, etc, finding a function definition can be as easy as Ctrl-f: myFunc:.
One approach is to modularize the class, and split it across multiple files. Typically this approach is used to provide plugins to a core class. jQuery is a great example of where the class has been extended using plugins.
When you're not interested in splitting the same class across multiple files, I find alphabetizing the function order helps.
In the end the order of the functions shouldn't matter so long as you have a good enough IDE that it lets you jump to the definition for that function.
God objects are an anti-pattern and a good indicator that you have some serious design flaws.
If you follow the single responsability principle and have a smart IDE that supports intellisense and other similar features, the investment for trying to keep everything ordered is not worth and not necessary since that would be the IDE's job to show all function definitions ordered in a panel for quick-access and to have a global overview.
If you really want to order your functions you could have an automated process that keeps your object literals structured.
However that doesn't mean you shouldn't have any coding standards. I also still organize my code in a way that makes sense e.g. private/public/priviledged members together.
I was watching a talk on clean code by Misko Hevery, and he mentioned trying to write a program with no if statements in them (well, as few as humanly possible) in order to simulate working on... Smalltalk or some such language, where polymorphism is preferred over inline conditional behavior.
To my limited understanding, functional programming is hard for only-imperative-so-far programmers like me - because our state changing methodologies don't have a way to be expressed in functional programs. A function only takes a value and returns a value and knows nothing about state.
I have also seen JS being hailed as being able to support a functional model.
So is there a simple set of restrictions, similar to my first paragraph, which will enable me to try out the functional paradigm in a language I know and love - rather than learn a full new language (I'll do that eventually but I want to try the ethos right now)?
There are two meanings to the term "functional programming".
The first meaning is the ability of a program to manipulate functions. Not all languages can do this but javascript is one of the languages that can. Languages that can assign functions to variables, pass functions to arguments and return functions are called functional programming languages so javascript is functional as is.
In this sense, if you look at any modern javascript code with prevalent use of callbacks then you're already doing functional programming.
The second meaning of functional programming is the style of programming where the primary method of program composition is functions rather than variables. In this sense almost any language can be used in a functional style by avoiding variable assignments and loop structures (use recursion instead).
When you look at the functional community, what they mean by functional is the first meaning plus a very strong version of the second meaning -- that is, variables are not only avoided but banned. Languages like Haskell don't have the concept of variables. To handle side-effects and mutable state like I/O they use a concept called monads.
You don't have to go that far. Classical functional languages like Lisp and Forth allowed variables. You just have to avoid them where possible.
Lisp and Forth style functional programming is heavily driven by processing lists/arrays without assigning anything to temporary variables. To some people, this style is easier to read. Where in imperative style you'd do this:
var a = [1,2,3];
var b = 0;
for (var i=0;i=a.length;i++) {
b += a[i] * 2;
}
// result is in b
in functional style you'd do this:
[1,2,3].
map(function(x){return x*2}).
reduce(function(x,y){return x+y},0);
Conceptually, functional style makes it look like you're applying filters to the array instead of iterating through the array. If you've ever used command line tools like grep then you'd find this concept very familiar.
Notice that we haven't introduced any variable assignments at all in the functional style.
The three core array methods/functions in the functional style are: map, reduce and filter. With them you can avoid something like 90% of for-loops.
Great question.
For an in-depth answer, check out this classic (and awesome) paper by John Hughes -- Why Functional Programming Matters.
First, Hughes explains what functional programming is not about, and cites some weak arguments that proponents of FP use. Good stuff (but too long to quote here).
Second, Hughes explains what FP is about:
It is now generally accepted that modular design is the key to successful programming, and recent languages such as Modula-II [6] and Ada [5] include features specifically designed to help improve modularity. However, there is a very important point that is often missed. When writing a modular program to solve a problem, one first divides the problem into subproblems, then solves the subproblems, and finally combines the solutions. The ways in which one can divide up the original problem depend directly on the ways in which one can glue solutions together. Therefore, to increase one’s ability to modularize a problem conceptually, one must provide new kinds of glue in the programming language. Complicated scope rules and provision for separate compilation help only with clerical details — they can never make a great contribution to modularization.
We shall argue in the remainder of this paper that functional languages provide two new, very important kinds of glue. We shall give some examples of programs that can be modularized in new ways and can thereby be simplified. This is the key to functional programming’s power — it allows improved modularization. It is also the goal for which functional programmers must strive — smaller and simpler and more general modules, glued together with the new glues we shall describe.
(emphasis mine)
So to get back to the original question, in order to do FP in Javascript, you'll want to build programs by implementing separate modules, then gluing them together. Javascript comes with some nice glue, and you can build even more glue on your own -- check out combinators.
You should try to avoid features that prevent you from using glue to combine modular pieces of code, for example:
mutable state -- especially if it's global
statements -- you can't pass while-loops as function arguments
some kinds of syntax, such as operators or property access -- you can't assign + to a variable or pass it as an argument
(These issues can, of course, be mitigated to a certain extent -- check out Javascript FP libraries for examples.)
On the other hand, features that aren't functions -- such as classes, objects, inheritance, prototypes, etc. -- don't necessarily stop you from using Javascript's glue, so there's no reason, from an FP standpoint, not to use them.
I want to know differences between the two following approaches from efficiency or any other point of views:(these codes are written using HTML5 Canvas)
first one has separate functions including drawScreen() function and event handling functions which all call the drawScreen().
the other one has a function canvasApp() which contains all the functions including drawScreen() inside along with other functions for handling the events. these function again call the drawScreen function inside themselves.
the codes are so long but if the explanation is not clear enough I will put the codes.
It sounds like you either want to have one function that takes a parameter which indicates which function to call, or you want to simply call each function directly. Please correct me if I am wrong.
I would personally go with the separate options. I don't see what encapsulating them inside a global function would bring in terms of functionality or simplicity. As long as the functions are clearly defined and documented I believe this is probably the best approach.
I would be more than happy to give you a more detailed answer, but you are going to have to enlighten us a bit more on your overall architecture (maybe with some pseudocode).
This is a rather religious question.
Javascript is a programming language which combines concepts from procedural, functional and object-oriented programming, so it allows to work in a lot of different programming paradigms.
Option one would be the procedural approach, while two would be the object-oriented approach. We could now have an endless discussion about which programming paradigm is the best, but we would never come to a result.
You have to know for yourself which programming style suits you best and suits your application best.
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.
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