The code should be as readable and understandable. This requires a good style of writing code. In this chapter, we will look at the components of this style.
Syntax
Cheat Sheet with syntax rules:
We analyze the main points.
Braces
Written on the same line, the so-called "Egyptian" style. Before the bracket - a space.
If you already have experience in development and you are used to making brackets on a separate line - this is also an option. In the end, you decide. But in the main JavaScript frameworks (jQuery, Dojo, Google Closure Library, Mootools, Ext.JS, YUI ...) the style is exactly that.
If the condition and code are short enough, for example if (cond) return null;
, then writing in one line is quite readable ... But, as a rule, a separate line is still perceived better.
Line length
The maximum length of the string is agreed in the command. As a rule, it is either 80
or 120
characters, depending on what monitors the developers have.
Longer lines need to be broken. If this is not done, the translation of a very long line will be made by the editor, and this may be less beautiful and readable.
Indentation
Indenting need two types:
- Horizontal indent, with nesting - two (or four) spaces.
As a rule, spaces are used because they allow you to make more flexible "configuration indentation" than the symbol "Tab".
For example:
1 | function removeClass(obj, cls) { |
4 | className = obj.className; |
Variables are declared vertically here, because In general, the human eye perceives (“scans”) vertically aligned information better than horizontally. This is a well-known fact among designers and to us, programmers, it will also be useful for better organization of the code.
- Vertical indent, for better breakdown of the code - line feed.
Used to separate logical blocks within a single function. In the example below, the functions pow
, data x,n
and their if
processing are separated.
Insert an extra line feed where it makes the code more readable. There should not be more than 9 lines of code in a row without vertical indent.
Semicolon
Semicolons should be set, even if they seem to be missing.
There are languages in which the semicolon is optional, and nobody puts it there. In JavaScript, it is also not required, but you need to install. What is the difference?
It is that subtle errors are possible in JavaScript without a semicolon. You will see some examples later in the tutorial. Such is the feature of syntax. And therefore it is recommended to always put it.
Naming
General rule:
- The variable name is a noun.
- The function name is a verb or begins with a verb. It happens that the names for short make nouns, but the verbs are clearer.
For names, English is used (not translit) and camel notation.
For more details, read about function names and variable names.
Nesting levels
There should be few nesting levels.
For example, it is better to do checks in cycles through “continue” so that there is no additional level if(..) { ... }
:
Instead:
1 | for ( var i=0; i<10; i++) { |
Use:
1 | for ( var i=0; i<10; i++) { |
2 | if (i не подходит) continue ; |
The situation is similar with if/else
and return
. The following two designs are identical.
First:
Second:
If there is a return
in the if
block, then the else
is not needed.
It is better to quickly handle simple cases, return the result, and then deal with the complex, without an additional level of nesting.
In the case of the isEven
function, it would be easier to proceed:
.. It would seem, you can go further, there is an even shorter version:
... However, the code
!(n % 2)
less obvious than
n % 2 == 0
. Therefore, in fact, the latter is worse.
The main thing for us is not the brevity of the code, but its simplicity and readability. Functions = Comments
Functions should be small. If the function is large - it is desirable to break it into several.
This rule is difficult to follow, but worth it. What is the comment here?
Calling a separate small function is not only easier to debug and test - the fact of its presence is an excellent comment .
Compare, for example, the two showPrimes(n)
functions to display primes up to n
.
First option:
01 | function showPrimes(n) { |
03 | for ( var i=2; i<n; i++) { |
05 | for ( var j=2; j<i; j++) { |
06 | if ( i % j == 0) continue nextPrime; |
The second option is the subfunction isPrime(n)
to check for simplicity:
01 | function showPrimes(n) { |
03 | for ( var i=2; i<n; i++) { |
04 | if (!isPrime(i)) continue ; |
11 | for ( var i=2; i<n; i++) { |
12 | if ( n % i == 0) return false ; |
The second option is simpler and clearer, isn't it? Instead of a piece of code, we see a description of the action that takes place there (check isPrime
).
Functions - under code
There are two ways to arrange the functions necessary to execute code.
- Functions on the code that uses them:
02 | function createElement() { |
06 | function setHandler(elem) { |
10 | function walkAround() { |
15 | var elem = createElement(); |
- First the code, and the functions below:
02 | var elem = createElement(); |
08 | function createElement() { |
12 | function setHandler(elem) { |
16 | function walkAround() { |
... In fact, there is still a third "style" in which the functions are randomly scattered around the code, but this is not our method, is it?
As a rule, it is better to allocate functions under the code that uses them. That is, this is the 2nd way.
The fact is that when reading such a code, we want to know first of all what it does , and only then what functions help it. If the code goes first, then it just gives the necessary information. As for the functions, it is quite possible that we will not need to read them, especially if they are adequately named and what they are doing is understandable.
The first method, however, has the advantage that at the time of reading we already know what functions exist.
Thus, if no one thinks about the names of functions, it may be the best choice. Try both options, but in my practice, the second one is preferable.
Comments
The code needs comments. They can be divided into several types.
- Reference comment before the function - about what exactly it does, what parameters it takes and what it returns.
For such comments, there is a JSDoc syntax.
Such comments are processed by many editors, such as Aptana and the editors from JetBrains. They take them into account when autocompleting.
- A brief comment on what exactly happens in this block of code.
In good code, it is rarely needed, since everything is clear from the variables, function names.
- There are several ways to solve the problem. Why was this one chosen?
As a rule, it is possible to understand from the code what it does. Of course, everything happens, but in the end, you see this code. Much more important may be what you do not see !
Why is this done that way? To this the response code itself does not give.
For example, you tried to solve the problem differently, but it did not work out - write about it. Why did you choose this particular solution? This is especially important in cases when not the first method that comes to mind, but some other one is used.
Without this, for example, this situation is possible:
- You open the code that was written some time ago, and you see that it is “non-optimal”.
- You think: "What a fool I was," and rewrite under the "more obvious and correct" option.
- ... The rush, of course, is good, but only this option you have already thought about before. And they refused, and why - they forgot. In the process of rewriting, they remembered, of course (fortunately), but the result was a loss of time to re-think.
Comments that explain code behavior are very important. They help to understand what is happening and make the right decision about the development of the code.
- What non-obvious features does this code provide? Where else in the code are they used?
In a good code should be at least unobvious. But where it is - please comment.
- The architectural commentary is “how it is, in general, arranged.” Applied technologies, interaction flow. For this, in particular, UML is used, but it is possible without it. The main thing is to be understood.
What is interesting, in the code of novice developers, most of the comments are usually of type 2. But in fact, these comments are the most unnecessary. And the thing is that people are too lazy to invent the correct names and structure the functions. Well nothing. Life will force: /
Style guides
When a whole team is involved in writing a project, there should be one code standard describing where and when to put spaces, commas, line breaks, etc.
Now, when there are so many finished projects, it makes no sense to invent your entire style guide. You can take already ready, and to which, if desired, you can always add something.
Most are in English, let me know if you find a good translation:
- Google JavaScript Style Guide
- JQuery Core Style Guidelines
- Idiomatic.JS (there is a translation)
- Dojo Style Guide
In order to begin development, the elements of styles indicated in this chapter will suffice. In the future, look at these guides, find "your" style.
Automated Check Tools
There are online services that check the style of the code.
The most famous are:
- JSLint - checks the code for compliance with the JSLint style, in the online interface, you can enter the code at the top, and various test settings at the bottom to make it softer.
- JSHint is another version of JSLint that weakens requirements in a number of places.
- Closure Linter - check for compliance with the Google JavaScript Style Guide.
All of them are also available in the form of programs that can be downloaded.
Total
The described principles of code design are relevant in most projects. There are other useful conventions.
Following (or not following) them, it is necessary to remember that any style tips are good only when they make the code more readable, understandable, easier to maintain.
Importance: 4
You may have noticed the following disadvantages:
- There are no spaces - between the parameters, around operators, with the nested call
alert(pow(...))
. - The variables
x
and n
assigned without var
. - Braces are located on a separate line.
- Logically different code fragments:
prompt
input and its if
processing are not separated by a vertical space. - The string with
alert
too long, it is better to split it into two. - Not everywhere there are semicolons.
[Open task in new window]
Importance: 4
The main error is the wrong choice of the function name result
.
- First, it is a noun, and therefore there can be no function (unless there is any special agreement on naming).
- Secondly, the
result
variable is traditionally used to store the “current result of a function”. Here this tradition is broken.
How to call a function correctly? One option is the prefix do
, i.e. doPow
, it means that this function does the actual work.
Also not the best option - check with the comment. Typically, the code becomes more readable if you make unobvious actions in a new function. In this case, the name of this function will serve as a comment.
PS Recursion during exponentiation is not the best choice, a normal cycle will be faster, but this is more a flaw in logic than an error of style.
Corrected code:
09 | function isNatural(n) { |
10 | return n >= 1 && n == Math.round(n); |
13 | function doPow(x, n) { |
14 | return (n == 1) ? x : x*doPow(x, n-1); (n == 1) ? x : x*doPow(x, n-1); |
[Open task in new window]
Comments
To leave a comment
Scripting client side JavaScript, jqvery, BackBone
Terms: Scripting client side JavaScript, jqvery, BackBone