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 3 years ago.
Improve this question
In the book Javascript: The Good Parts by Douglas Crockford, this is all the author has to say about the continue Statement:
The continue statement jumps to the top of the loop. I have never seen a piece of code that was not improved by refactoring it to remove the continue statement.
This really confuses me. I know Crockford has some very opinionated views on JavaScript, but this just sounds entirely wrong to me.
First of all, continue does more than just jump to the top of a loop. By default, it also progresses to the next iteration. So isn't Crockford's statement just completely false information?
More importantly, I do not entirely understand why continue would even be considered to be bad. This post provides what seems to be the general assumption:
Why is continue inside a loop a bad idea?
Although I understand how continue may make code difficult to read in certain instances, I think it is just as likely that it can make code more readable. For instance:
var someArray=['blah',5,'stuff',7];
for(var i=0;i<someArray.length;i++){
if(typeof someArray[i]==='number'){
for(var j=0;j<someArray[i];j++){
console.log(j);
}
}
}
This could be refactored into:
var someArray=['blah',5,'stuff',7];
for(var i=0;i<someArray.length;i++){
if(typeof someArray[i]!=='number'){
continue;
}
for(var j=0;j<someArray[i];j++){
console.log(j);
}
}
continue isn't particularly beneficial in this specific example, but it does demonstrate the fact that it reduces the nesting depth. In more complex code, this could potentially increase readability.
Crockford provides no explanation as to why continue should not be used, so is there some deeper significance behind this opinion that I am missing?
The statement is ridiculous. continue can be abused, but it often helps readability.
Typical use:
for (somecondition)
{
if (!firsttest) continue;
some_provisional_work_that_is_almost_always_needed();
if (!further_tests()) continue;
do_expensive_operation();
}
The goal is to avoid 'lasagna' code, where you have deeply nested conditionals.
Edited to add:
Yes, this is ultimately subjective. Here's my metric for deciding.
Edited one last time:
This example is too simple, of course, and you can always replace nested conditionals with function calls. But then you may have to pass data into the nested functions by reference, which can create refactoring problems at least as bad as the ones you're trying to avoid.
Douglas Crockford may feel this way because he doesn't believe in assignment within a conditional. In fact, his program JSlint doesn't even let you do it, even though Javascript does. He would never write:
Example 1
while (rec = getrec())
{
if (condition1(rec))
continue;
doSomething(rec);
}
but, I'm guessing he would write something like:
Example 2
rec = getrec();
while (rec)
{
if (!condition(rec))
doSomething(rec);
rec = getrec();
}
Both of these work, but if you accidentally mix these styles you get an infinite loop:
Example 3
rec = getrec();
while (rec)
{
if (condition1(rec))
continue;
rec = getrec();
}
This could be part of why he doesn't like continues.
I am personally on the other side than the majority here. The problem is usually not with the shown continue patterns, but with more deeply nested ones, where possible code paths may become hard to see.
But even your example with one continue does not show improvement in my opinion that is justifiable. From my experience a few continue statements are a nightmare to refactor later (even for static languages better suited for automated refactoring like Java, especially when someone later puts there break too).
Thus, I would add a comment to the quote you gave:
Refactoring to remove continue statement inreases your further ability to refactor.
And inner loops are really good candidated for e.g. extract function. Such refactoring is done when the inner loop becomes complex and then continue may make it painful.
These are my honest opinions after working professionally on JavaScript projects in a team, there rules that Douglas Crockford talks about really show their merits.
Continue is an extremely useful tool for saving computation cycles in algorithms. Sure, it can be improperly used but so can every other keyword or approach. When striving for performance, it can be useful to take an inverse approach to path divergence with a conditional statement. A continue can facilitate the inverse by allowing less efficient paths to be skipped when possible.
Actually, from all the analysis it seems:
If you have shallow loops - feel free to use continue iff it improves readability (also, there may be some performance gains?).
If you have deep nested loops (which means you already have a hairball to untangle when you re-factor) avoiding continue may prove to be beneficial from a code reliability standpoint.
In defense of Douglas Crokford, I feel that his recommendations tend to lean towards defensive programming, which, in all honesty seems like a good approach for 'idiot-proofing' the code in the enterprise.
Personally, I have never heard anything bad about using the continue statement. It is true that it could (most of the time) be easily avoided, but there is no reason to not use it. I find that loops can be a lot cleaner looking and more readable with continue statements in place.
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 5 years ago.
The community reviewed whether to reopen this question 2 months ago and left it closed:
Needs details or clarity Add details and clarify the problem by editing this post.
Improve this question
What is the current standard in 2017 in Javascript with for() loops vs a .forEach.
I am currently working my way through Colt Steeles "Web Dev Bootcamp" on Udemy and he favours forEach over for in his teachings. I have, however, searched for various things during the exercises as part of the course work and I find more and more recommendations to use a for-loop rather than forEach. Most people seem to state the for loop is more efficient.
Is this something that has changed since the course was written (circa 2015) or are their really pros and cons for each, which one will learn with more experience.
Any advice would be greatly appreciated.
for
for loops are much more efficient. It is a looping construct specifically designed to iterate while a condition is true, at the same time offering a stepping mechanism (generally to increase the iterator). Example:
for (var i=0, n=arr.length; i < n; ++i ) {
...
}
This isn't to suggest that for-loops will always be more efficient, just that JS engines and browsers have optimized them to be so. Over the years there have been compromises as to which looping construct is more efficient (for, while, reduce, reverse-while, etc) -- different browsers and JS engines have their own implementations that offer different methodologies to produce the same results. As browsers further optimize to meet performance demands, theoretically [].forEach could be implemented in such a way that it's faster or comparable to a for.
Benefits:
efficient
early loop termination (honors break and continue)
condition control (i<n can be anything and not bound to an array's size)
variable scoping (var i leaves i available after the loop ends)
forEach
.forEach are methods that primarily iterate over arrays (also over other enumerable, such as Map and Set objects). They are newer and provide code that is subjectively easier to read. Example:
[].forEach((val, index)=>{
...
});
Benefits:
does not involve variable setup (iterates over each element of the array)
functions/arrow-functions scope the variable to the block
In the example above, val would be a parameter of the newly created function. Thus, any variables called val before the loop, would hold their values after it ends.
subjectively more maintainable as it may be easier to identify what the code is doing -- it's iterating over an enumerable; whereas a for-loop could be used for any number of looping schemes
Performance
Performance is a tricky topic, which generally requires some experience when it comes to forethought or approach. In order to determine ahead of time (while developing) how much optimization may be required, a programmer must have a good idea of past experience with the problem case, as well as a good understanding of potential solutions.
Using jQuery in some cases may be too slow at times (an experienced developer may know that), whereas other times may be a non-issue, in which case the library's cross-browser compliance and ease of performing other functions (e.g., AJAX, event-handling) would be worth the development (and maintenance) time saved.
Another example is, if performance and optimization was everything, there would be no other code than machine or assembly. Obviously that isn't the case as there are many different high level and low level languages, each with their own tradeoffs. These tradeoffs include, but are not limited to specialization, development ease and speed, maintenance ease and speed, optimized code, error free code, etc.
Approach
If you don't have a good understanding if something will require optimized code, it's generally a good rule of thumb to write maintainable code first. From there, you can test and pinpoint what needs more attention when it's required.
That said, certain obvious optimizations should be part of general practice and not required any thought. For instance, consider the following loop:
for (var i=0; i < arr.length; ++i ){}
For each iteration of the loop, JavaScript is retrieving the arr.length, a key-lookup costing operations on each cycle. There is no reason why this shouldn't be:
for (var i=0, n=arr.length; i < n; ++i){}
This does the same thing, but only retrieves arr.length once, caching the variable and optimizing your code.
validationError([elem1,elem2],type,shiftNo);
or
var arr = [elem1,elem2];
validationError(arr,type,shiftNo);
What I mean to ask is approach 1 of calling the function considered bad ( also does it have any performance ramifications). and for that matter is it a bad approach to declare strings, object and functions inside arguments.
Performance is not an issue, not in a language like JS, Ruby or whatnot. So all we can do is think about code readability. And this case is not strongly related to JS, so will be my examples.
move = ["E2", "E4"];
if chessboard.valid(move, player) {
...
}
This clearly states: "if the move (E2 E4) is valid for this chessboard, then...", you don't even need to look at the docs to know that. If we write that without assigning our array a name, the result looks a little cryptic (still easy to guess, but harder for such a tiny example):
if chessboard.valid(["E2", "E4"], player) {
...
}
What is this supposed to mean? What does valid stand for here? Maybe, it's asking whether these cells contain valid player's pieces? This is a sympthom of a design flaw, more precisely bad naming. It makes bold assumptions about how the chessboard code will be used. We can make it obvious that this array represents a move by renaming the chessboard's method:
if chessboard.valid_move(["E2", "E4"], player) {
...
}
This is better, but you may not have an API that allows your code to stay so readable without some additional naming.
So, I suggest a rule of thumb:
If the array will be used more than once, name it.
If the meaning of the array is not obvious from where it goes (function name), name it.
Don't name it, unless points 1 or 2 apply.
It doesn't make any difference really. Either way, you create a Javascript Array, which basically is an Object and get a reference in return (which you pass to your method). If you don't need to access that array (or other data) later in your code, the second approach is completely fine.
Are the contents of arr ever going to get used again? If so, then option 2 is definitely the way to go. If not... something as simple as this is probably just personal opinion.
Personally, I'd have to say that option 2 is better practice, even though sometimes I'm guilty of using option 1. Option 2 is easier to read, it's easier to follow and it's less likely someone will have to re-read it because they became temporarily confused or lost in flow of thought whilst reading through your code (especially newer programmers). For those reasons it's easier to maintain, you, and potentially future developers working with your code, will likely save time working with it.
The only negatives I can see would be generating an absolutely miniscule amount of overhead, and now you have 2 lines of code instead of 1. But I think that's irrelevant, the tiny potential benefits of option 2 outweigh the tiny negatives of option 1.
It is subjective, but in my opinion it is better to use the second approach.
As #jAndy said there is no difference in the code execution neither the performance of your code, but it is easier to debug and easier to read and understand the second approach.
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Javascript Try-Catch Performance Vs. Error Checking Code
A colleague of mine told me that using a lot of try catch blocks in javascript is going to be a hit in performance . Is that claim true and if yes then why ?
Short answer, yes he is correct. A try/catch statement has do to certain things under the hood in order to work. For instance, it will extend the scope lookup chain (which might not be that big problem in modern environments) but it especially needs to evaluate whatever code is within that try-block, to figure if there are any errors thrown.
Anyway, try/catch blocks are a great opportunity to make your code stable. However, you should always apply it on the smallest fraction of your code possible and of course only, if it is really needed (like, avoiding browser specific bugs/errors which you can't work around). Just putting like all of your script into one big try/catch block, is certainly the worst idea.
Yes. There is a good article on that at dev.opera.com.
This is likely because try-catch-blocks have that certain, unusual handling of result objects, they need to check whether its type is throw. And then, executing the catch block is not as easy as it looks in the code. See Ecmascript ยง12.14: The try Statement for further reading.
Still, try-catch-clauses are a powerful feature, and one should use them where appropriate and useful. But instead of having them inside performance-critical functions, you should wrap them around so they are not executed too often.
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.