


Modern JavaScript development programming style Idiomatic.js guide Chinese version_javascript skills
The style you choose for your project should be of the highest standards. Place it as a description in your project and link to this document as a guarantee of code style consistency, readability, and maintainability.
1. Blank
1. Never mix spaces and tabs.
2. Start a project and before writing code, choose soft indentation (spaces) or Tab (as the indentation method) and use it as the highest guideline.
a). For readability, I always recommend designing 2-letter indents in your editors — this is equivalent to two spaces or two spaces instead of one tab.
3. If your editor supports it, please always turn on the "Show invisible characters" setting. The benefits are:
a). Ensure consistency
b). Remove spaces at the end of lines
c). Remove spaces on empty lines
d). Submission and comparison are more readable
2. Beautify grammar
A. Parentheses, curly braces, line breaks
// if/else/for/while/try usually have parentheses, braces and multiple lines
// This helps with readability
// 2.A.1.1
// Examples of crapped syntax
if(condition) doSomething();
while(condition) iterating ;
for(var i=0;i<100;i ) someIterativeFn();
// 2.A.1.1
// Use spaces to improve readability
if ( condition ) {
// Statement
}
while ( condition ) {
// Statement
}
for ( var i = 0; i < 100; i ) {
// Statement
}
// Better approach:
var i,
length = 100;
for ( i = 0; i < length; i ) {
// statement
}
// Or...
var i = 0,
length = 100;
for ( ; i < length; i ) {
// statement
}
var prop;
for ( prop in object ) {
// Statement
}
if ( true ) {
// Statement
} else {
// Statement
}
B. Assignment, declaration, function (named function, function expression , constructor function)
// 2.B.1.1
// Variable
var foo = "bar",
num = 1,
undef;
//Literal identifier:
var array = [],
object = {};
// 2.B.1.2
// Using only one `var` within a scope (function) helps improve readability
// and keeps your declaration list organized (Also saves you a few keystrokes)
// Bad
var foo = "";
var bar = "";
var qux;
// OK
var foo = "",
bar = "",
quux;
// Or..
var // Comments on these variables
foo = "",
bar = "",
quux;
// 2.B.1.3
// `var` statements must always be at the top of their respective scopes (functions)
// Also works with constants from ECMAScript 6
// Bad
function foo() {
// There is a statement before the variable
var bar = "",
qux;
}
// OK
function foo() {
var bar = "",
qux;
// All statements are after variables
}
// 2.B.2.1
// Named function declaration
function foo( arg1, argN ) {
}
// Usage
foo( arg1, argN );
// 2.B.2.2
// Named function declaration
function square( number) {
return number * number;
}
// How to use
square( 10 );
// Very unnatural continuation passing style
function square( number, callback) {
callback( number * number );
}
square( 10, function( square ) {
// callback content
});
// 2.B.2.3
// Function expression
var square = function( number) {
// Return valuable and relevant content
return number * number;
};
// Function expression with identifier
// This preferred form has additional functionality that allows it to call itself
// and has the identifier on the stack
var factorial = function factorial ( number ) {
if ( number < 2 ) {
return 1;
}
return number * factorial( number-1 );
};
// 2.B.2.4
// Constructor declaration
function FooBar( options) {
this.options = options;
}
// Usage
var fooBar = new FooBar({ a: "alpha" });
fooBar.options;
// { a: "alpha" }
C. Exceptions, details
// 2.C.1.1
// Function with callback
foo(function() {
// Note: the parentheses and `function` in the first function call There are no spaces
});
// The function accepts `array` as parameter, no spaces
foo([ "alpha", "beta" ]);
// 2.C.1.2
// The function accepts `object` as a parameter, no spaces
foo({
a: "alpha",
b: "beta"
});
// The function accepts `string` literal as parameter, no spaces
foo("bar");
//There are no spaces inside the parentheses used for grouping
if ( !("foo" in obj) ) {
}
D. Consistency Always Wins
In Sections 2.A-2.C, white space is proposed as a recommended approach based on a simple, higher purpose: unity. It's worth noting that formatting preferences like "internal white space" must be optional, but only one type must exist in the entire project's source code.
// 2.D.1.1
if (condition) {
// Statement
}
while (condition) {
// Statement
}
for (var i = 0; i < 100; i ) {
// Statement
}
if (true) {
// Statement
} else {
// Statement
}
E. Quotes
It doesn’t matter whether you choose single quotes or double quotes, they make no difference in parsing in JavaScript. What absolutely needs to be enforced is consistency. Never mix two types of quotes in the same project, choose one, and be consistent.
F. End of line and blank line
Leaving white space will destroy the distinction and make the use of changes unreadable. Consider including a pre-commit hook to automatically remove spaces at the end of lines and in empty lines.
3. Type detection (from jQuery Core Style Guidelines)
A. Direct types (actual types, Actual Types)
String:
typeof variable === "string "
Number:
typeof variable = == "number"
Boolean:
typeof variable === "boolean"
Object:
typeof variable === "object"
Array:
Array.isArray( arrayLikeObject )
(if possible)
Node:
elem.nodeType === 1
null:
variable === null
null or undefined:
variable == null
undefined:
Global variables:
typeof variable === " undefined"
Local variable:
variable === undefined
Attribute:
object.prop === undefined
object.hasOwnProperty( prop )
"prop" in object
B. Conversion type (forced type, Coerced Types)
Consider the meaning of this...
Given HTML:
// 3.B.1.1
// `foo` has been assigned the value `0` and the type is `number`
var foo = 0;
// typeof foo;
// "number"
...
// In subsequent code, you need to update `foo` to give the new value obtained in the input element
foo = document.getElementById("foo-input").value;
// If you now test `typeof foo`, the result will be `string`
// This means that your if statement to detect `foo` has logic similar to this:
if ( foo === 1 ) {
importantTask();
}
// `importantTask()` will never be executed even if `foo` has a value "1"
// 3.B.1.2
// You can cleverly use the / - unary operator to cast the type to solve the problem:
foo = document.getElementById("foo-input").value;
// ^ The unary operator converts the operand on its right side into `number`
// typeof foo;
// "number"
if ( foo === 1 ) {
importantTask();
}
// `importantTask()` will be called
For casts here are a few examples:
// 3.B.2.1
var number = 1,
string = "1",
bool = false;
number;
// 1
number "";
// "1"
string;
// "1"
string;
// 1
string ;
// 1
string;
// 2
bool;
// false
bool;
// 0
bool "";
// "false"
// 3.B.2.2
var number = 1,
string = "1",
bool = true;
string === number;
// false
string === number "";
// true
string === number;
// true
bool === number;
// false
bool === number;
// true
bool === string;
// false
bool === !!string;
// true
// 3.B.2.3
var array = [ "a", "b", "c" ];
!!~array.indexOf("a");
// true
!!~array.indexOf("b");
// true
!!~array.indexOf("c");
// true
!!~array.indexOf("d");
// false
// It is worth noting that the above are "unnecessarily clever"
// Use a clear solution to compare the returned values
// Such as indexOf:
if ( array.indexOf( "a" ) >= 0 ) {
// ...
}
// 3.B.2.3
var num = 2.5;
parseInt( num, 10 );
// Equivalent to...
~~num;
num >> 0;
num >>> 0;
//The result is always 2
// Always keep in mind that negative values will be treated differently...
var neg = -2.5;
parseInt( neg, 10 );
// Equivalent to...
~~neg;
neg >> 0;
// The result is always -2
// But...
neg >>> 0;
//The result is 4294967294
4. Comparison operation
// 4.1.1
// When just judging whether an array has a length, use this instead:
if ( array.length > 0 ) ...
// ...To determine authenticity, please use this:
if (array.length) ...
// 4.1.2
// When just judging whether an array is empty, use this instead:
if (array.length === 0) ...
// ...To determine authenticity, please use this:
if ( !array.length ) ...
// 4.1.3
// When just judging whether a string is empty, use this instead:
if ( string !== "" ) ...
// ...To determine authenticity, please use this:
if ( string ) ...
// 4.1.4
// When just judging whether a string is empty, use this instead:
if ( string === "" ) ...
// ...To determine authenticity, please use this:
if ( !string ) ...
// 4.1.5
// When just judging whether a reference is true, use this instead:
if ( foo === true ) ...
// ... judge just as you think and enjoy the benefits of built-in functions:
if ( foo ) ...
// 4.1.6
// When just judging whether a reference is false, use this instead:
if ( foo === false ) ...
// ...convert it to true using an exclamation mark
if ( !foo ) ...
// ...It should be noted that: this will match 0, "", null, undefined, NaN
// If you _must_ be false of Boolean type, please use it like this:
if ( foo === false ) ...
// 4.1.7
// If you want to calculate a reference, it may be null or undefined, but it is not false, "" or 0,
// Instead of using this:
if ( foo === null || foo === undefined ) ...
// ...enjoy the benefits of == type casting, like this:
if ( foo == null ) ...
// Remember, using == will make `null` match `null` and `undefined`
// but not `false`, "" or 0
null == undefined
Always judge the best and most accurate value, the above is a guideline not a dogma.
// 4.2.1
// Type conversion and comparison operation instructions
// `===` first, `==` second (unless loosely typed comparison is required)
// `===` never does type conversion, which means:
"1" === 1;
// false
// `==` will convert the type, which means:
"1" == 1;
// true
// 4.2.2
// Boolean, True & False
// Boolean:
true, false
// True:
"foo", 1
// Pseudo:
"", 0, null, undefined, NaN, void 0
5. Practical style
// 5.1.1
// A practical module
(function( global ) {
var Module = (function() {
var data = "secret";
return {
// This is a boolean value
bool: true,
bool: true,
// A string
string: "a string",
// An array
array: [ 1, 2, 3, 4 ],
// An object
object: {
lang: "en-Us"
},
getData: function() {
. data = value );
}
};
})();
// Some others will appear here
// Turn your module into a global object
})( this );
// 5.2.1
(function( global ) {
function Ctor( foo ) {
this.foo = foo;
return this;
}Ctor.prototype.getFoo = function() {
return this.foo;
};
Ctor.prototype.setFoo = function( val ) {
return ( this.foo = val );
};
// Instead of using `new` to call the constructor, you might do this:
var ctor = function( foo ) {
return new Ctor( foo );
// Turn our constructor into a global object
global.ctor = ctor;
6. Naming
A. You are not a human compiler/compressor, so try to become one.
The following code is an example of extremely bad naming:
// 6.A.1.1
// Poorly named example code
function q(s) {
return document.querySelectorAll(s);
}
var i,a=[],els=q("#foo");
for( i=0;i
No doubt, you have written such code - I hope it will never appear again from today.
Here is a code for the same logic, but with more robust, appropriate naming (and a readable structure):
// 6.A.2.1
// Improved naming example code
function query( selector ) {
return document.querySelectorAll( selector );
}
var idx = 0,
elements = [],
matches = query("#foo"),
length = matches.length;
for ( ; idx < length; idx ) {
elements.push( matches[ idx ] );
}
Some additional naming tips:
// 6.A.3.1
// Named string
`dog` is a string
// 6.A.3.2
// Named arrays
`['dogs']` is an array
containing the `dog string// 6.A.3.3
// Named functions, objects, instances, etc.
camlCase; function and var declaration
// 6.A.3.4
// Named builders, prototypes, etc.
PascalCase; constructor function
// 6.A.3.5
// Named regular expressions
rDesc = //;
// 6.A.3.6
// From Google Closure Library Style Guide
functionNamesLikeThis;
variableNamesLikeThis;
ConstructorNamesLikeThis;
EnumNamesLikeThis;
methodNamesLikeThis;
SYMBOLIC_CONSTANTS_LIKE_THIS;
B. Face this
In addition to using the well-known call and apply, always prefer .bind( this ) or a functional equivalent to it. Create a BoundFunction declaration for subsequent calls, using aliases only when there is no better alternative.
// 6.B.1
function Device (opts) {
this.value = null;
// Create a new asynchronous stream, which will be called continuously
stream.read( opts.path, function( data ) {
// Use stream to return the latest value of data and update the value of the instance
this.value = data;
}.bind(this) );
// Control the frequency of event triggering
setInterval(function() {
// Emit a controlled event
this.emit("event");
}.bind(this), opts.freq || 100 );
}
// Assume we have inherited the event emitter (EventEmitter) ;)
When that doesn't work, functionality equivalent to .bind is available in most modern JavaScript libraries.
// 6.B.2
// Example: lodash/underscore, _.bind()
function Device( opts ) {
this.value = null;
stream.read( opts.path, _.bind(function( data ) {
this.value = data;
}, this) );
setInterval(_.bind(function() {
this.emit("event");
}, this), opts.freq || 100 );
}
// Example: jQuery.proxy
function Device( opts ) {
this.value = null;
stream.read( opts.path, jQuery.proxy(function( data ) {
this.value = data;
}, this) );
setInterval( jQuery.proxy(function() {
this.emit("event");
}, this), opts.freq || 100 );
}
// Example: dojo.hitch
function Device( opts ) {
this.value = null;
stream.read( opts.path, dojo.hitch( this, function( data ) {
this.value = data;
}) );
setInterval( dojo.hitch( this, function() {
this.emit("event");
}), opts.freq || 100 );
}
Provide a candidate to create an alias of this with self as the identifier. This is highly buggy and should be avoided if possible.
// 6.B.3
function Device( opts ) {
var self = this;
this.value = null;
stream.read( opts.path, function( data ) {
self.value = data;
});
setInterval(function() {
self.emit("event");
}, opts.freq || 100 );
}
C. Use thisArg
Several prototype methods in ES 5.1 have a special thisArg tag built in, use it as much as possible
// 6.C.1
var obj;
obj = { f: "foo", b: "bar", q: "qux" };
Object.keys( obj ).forEach(function( key ) {
// |this| is now `obj`
console.log( this[ key ] );
}, obj ); // <-- The last parameter is `thisArg`
//Print it out...
// "foo"
// "bar"
// "qux"
thisArg is in Array.prototype.every, Array.prototype.forEach, Array.prototype It can be used in .some, Array.prototype.map, and Array.prototype.filter.
7. Misc
The ideas and concepts that will be explained in this section are not dogma. Instead, it encourages curiosity about existing practices to try to provide better solutions for general JavaScript programming tasks.
A. Avoid using switch, modern method tracing will blacklist functions with switch expressions.
It seems that switch statements have been significantly improved in the latest versions of both Firefox and Chrome. http://jsperf.com/switch-vs-object-literal-vs-module
It is worth noting that the improvements can be seen here: https://github.com/rwldrn/idiomatic.js/issues/13
// 7.A.1.1
// Switch statement example
switch( foo ) {
case "alpha":
alpha();
break;
case "beta":
beta();
break;
default:
//Default branch
break;
}
// 7.A.1.2
// One way to support composition and reuse is to use an object to store "cases",
// Use a function to delegate:
var cases, delegator;
// Return value is for illustration only
cases = {
alpha: function() {
// Statement
// A return value
return [ "Alpha", arguments .length ];
},
beta: function() {
// Statement
// A return value
return [ "Beta", arguments.length ];
} ,
_default: function() {
// Statement
// A return value
return [ "Default", arguments.length ];
}
};
delegator = function() {
var args, key, delegate;
// Convert `argument` into an array
args = [].slice.call( arguments );
// Extract the first value from `argument`
key = args.shift();
// Call the default branch
delegate = cases._default;
// Delegate methods from the object
if ( cases.hasOwnProperty( key ) ) {
delegate = cases[ key ];
}
// The scope of arg can be set to a specific value,
// In this case, |null| is fine
return delegate.apply( null, args );
};
// 7.A.1.3
// Using the API in 7.A.1.2:
delegator( "alpha", 1, 2, 3, 4, 5 );
// [ "Alpha", 5 ]
// Of course the value of `case` key can be easily changed to any value
var caseKey, someUserInput;
// Is it possible that it is some form of input?
someUserInput = 9;
if ( someUserInput > 10 ) {
caseKey = "alpha";
} else {
caseKey = "beta";
}
// Or...
caseKey = someUserInput > 10 ? "alpha" : "beta";
// Then...
delegator( caseKey, someUserInput );
// [ "Beta", 1 ]
// Of course you can do it this way...
delegator();
// [ "Default", 0 ]
B. Returning the value early improves the readability of the code without much performance difference
// 7.B.1.1
// Bad:
function returnLate( foo ) {
var ret;
if ( foo ) {
ret = "foo";
} else {
ret = "quux";
}
return ret;
}
// OK:
function returnEarly( foo ) {
if ( foo ) {
return "foo";
}
return "quux";
}
8. Native & Host Objects (Note: In fact, I have always felt that Host Objects should not be translated, so I will translate it according to the way it is written in ordinary books)
The most basic principle is:
Don’t do anything stupid, things will get better.
To reinforce this idea, watch this demo:
“Everything is allowed: Native extensions” by Andrew Dupont (JSConf2011, Portland, Oregon)
http://blip.tv/jsconf/jsconf2011-andrew-dupont-everything-is-permitted-extending-built-ins-5211542
9. Notes
Single-line comments placed above the code are preferred
Multiple lines are also possible
End-of-line comments should be avoided!
The JSDoc method is also good, but it takes more time
10. Use one language
Programs should only be written in the same language, regardless of the language specified by the program maintainer (or team).
Appendix
Comma First
All projects that use this document as a basic style guide do not allow code formatting with leading commas unless explicitly specified or requested by the author.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

Introduction to how to use JavaScript and WebSocket to implement a real-time online ordering system: With the popularity of the Internet and the advancement of technology, more and more restaurants have begun to provide online ordering services. In order to implement a real-time online ordering system, we can use JavaScript and WebSocket technology. WebSocket is a full-duplex communication protocol based on the TCP protocol, which can realize real-time two-way communication between the client and the server. In the real-time online ordering system, when the user selects dishes and places an order

How to use WebSocket and JavaScript to implement an online reservation system. In today's digital era, more and more businesses and services need to provide online reservation functions. It is crucial to implement an efficient and real-time online reservation system. This article will introduce how to use WebSocket and JavaScript to implement an online reservation system, and provide specific code examples. 1. What is WebSocket? WebSocket is a full-duplex method on a single TCP connection.

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

Usage: In JavaScript, the insertBefore() method is used to insert a new node in the DOM tree. This method requires two parameters: the new node to be inserted and the reference node (that is, the node where the new node will be inserted).

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

JavaScript is a programming language widely used in web development, while WebSocket is a network protocol used for real-time communication. Combining the powerful functions of the two, we can create an efficient real-time image processing system. This article will introduce how to implement this system using JavaScript and WebSocket, and provide specific code examples. First, we need to clarify the requirements and goals of the real-time image processing system. Suppose we have a camera device that can collect real-time image data
