Modern JavaScript development programming style Idiomatic. js guide Chinese Version _ javascript skills

Source: Internet
Author: User
Tags hasownproperty
The following sections describe a reasonable modern JavaScript development style guide, not a hard rule. Thelawofcodestyleconsistency is a highly unified code style ). The style you choose for the project should be the highest criterion. Place the description in your project and link it to this document to ensure code style consistency, readability, and maintainability.

I. Blank

1. Do not mix spaces and tabs.
2. Start a project. before writing code, select soft indent (Space) or Tab (as indent mode) and use it as the highest criterion.
A). For readability, I always recommend that you design two letter-width indentation in your editing. This is equivalent to two spaces or two spaces to replace one Tab.
3. If your editor supports this function, always enable the "show invisible characters" setting. Benefits:
A). Ensure consistency
B) Remove the space at the end of the row.
C). Remove spaces from blank lines.
D). More readable submission and Comparison

Ii. Beautify syntax

A. Parentheses, curly braces, and line breaks

The Code is as follows:


// If/else/for/while/try usually have parentheses, curly braces, and multiple rows
// This is readable.

// 2. A.1.1
// Example of cramped 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 practice:

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 (name function, function expression, build function)

The Code is as follows:


// 2. B .1.1
// Variable
Var foo = "bar ",
Num = 1,
Undef;

// Literal identifier:
Var array = [],
Object = {};

// 2. B .1.2
// Using only one 'var 'in a single scope (function) helps improve readability
// And keep your declaration list in an orderly manner (also saves you a few mouse clicks)

// Not good
Var foo = "";
Var bar = "";
Var qux;

// Good
Var foo = "",
Bar = "",
Quux;

// Or ..
Var // comment on these variables
Foo = "",
Bar = "",
Quux;

// 2. B .1.3
// The 'var 'statement must always be at the top of the respective scopes (functions)
// It is also applicable to constants from ECMAScript 6

// Not good
Function foo (){

// A statement exists before the variable

Var bar = "",
Qux;
}

// Good
Function foo (){
Var bar = "",
Qux;

// All statements are after the variable
}
// 2. B .2.1
// Name function declaration
Function foo (arg1, argN ){

}

// Usage
Foo (arg1, argN );

// 2. B .2.2
// Name function declaration
Function square (number ){
Return number * number;
}

// Usage
Square (10 );

// A 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;
};

// A function expression with an identifier
// This preferred form has additional features so that it can call itself
// And there is an identifier in 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. exception, details

The Code is as follows:


// 2. C.1.1
// Functions with callback
Foo (function (){
// Note: there is no space in the parentheses and 'function' of the first function call.
});

// The function accepts 'array' as the parameter with no space.
Foo (["alpha", "beta"]);

// 2. C.1.2
// The function accepts 'object' as the parameter and has no space.
Foo ({
A: "alpha ",
B: "beta"
});

// The function accepts the 'string' literal as a parameter without spaces
Foo ("bar ");

// There is no space in the parentheses for grouping
If (! ("Foo" in obj )){

}


D. Consistency (unification) Always ends with a smile (Consistency Always Wins)

In section 2. A-2.C, the white space is proposed as a recommendation method, based on simple, higher purpose: unified. It is worth noting that formatting preferences, such as "Internal whitelist" must be optional, but there must be only one option in the source code of the entire project.

The Code is as follows:


// 2. D.1.1

If (condition ){
// Statement
}

While (condition ){
// Statement
}

For (var I = 0; I <100; I ++ ){
// Statement
}

If (true ){
// Statement
} Else {
// Statement
}


E. quotation marks

It doesn't matter whether you select single quotes or double quotes. In JavaScript, there is no difference in parsing them. Consistency is absolutely required. Never mix two quotation marks in the same project. Select one type and keep them consistent.

F. End and empty rows

The white space will damage the difference and the change will not be readable. Consider including a pre-submitted hook to automatically delete spaces at the end of the row and in the empty row.

Iii. type detection (from jQuery Core Style Guidelines)

A. Direct Type (Actual type, Actual Types)

String:

The Code is as follows:


Typeof variable = "string"


Number:

The Code is as follows:


Typeof variable = "number"


Boolean:

The Code is as follows:


Typeof variable = "boolean"


Object:

The Code is as follows:


Typeof variable = "object"


Array:

The Code is as follows:


Array. isArray (arrayLikeObject)
(If possible)


Node:

The Code is as follows:


Elem. nodeType = 1


Null:

The Code is as follows:


Variable = null


Null or undefined:

The Code is as follows:


Variable = null


Undefined:

Global variables:

The Code is as follows:


Typeof variable = "undefined"


Local variables:

The Code is as follows:


Variable = undefined


Attribute:

The Code is as follows:


Object. prop = undefined
Object. hasOwnProperty (prop)
"Prop" in object


B. Conversion Type (forced type, Coerced Types)

Consider the following meaning...

Given HTML:

The Code is as follows:


// 3. B .1.1

// 'Foo' has been assigned a value of '0' and the type is 'number'
Var foo = 0;

// Typeof foo;
// "Number"
...

// In subsequent code, you need to update 'foo' and assign the new value to the input element.

Foo = document. getElementById ("foo-input"). value;

// If you test 'typeof foo' now, the result will be 'string'
// This means that the if statement detects that 'foo' has a 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 skillfully use the +/-unary operator to forcibly convert the type to solve the problem:

Foo = + document. getElementById ("foo-input"). value;
// ^ + Unary operator converts the operation object on the right to 'number'

// Typeof foo;
// "Number"

If (foo = 1 ){

ImportantTask ();

}

// 'Importanttask () 'will be called


Here are several examples of forced type conversion:

The Code is as follows:


// 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 ("");
// True

!!~ Array. indexOf ("B ");
// True

!!~ Array. indexOf ("c ");
// True

!!~ Array. indexOf ("d ");
// False

// It is worth noting that the above are all "unnecessary cleverness"
// Use a clear solution to compare the returned values
// For example, indexOf:

If (array. indexOf ("a")> = 0 ){
//...
}
// 3. B .2.3

Var num = 2.5;

ParseInt (num, 10 );

// It is equivalent...

~~ Num;

Num> 0;

Num >>> 0;

// The result is both 2

// Keep in mind that negative values will be treated differently...

Var neg =-2.5;

ParseInt (neg, 10 );

// It is equivalent...

~~ Neg;

Neg> 0;

// The result is-2.
//...

Neg> 0;

// Result is 4294967294

Iv. Comparison

The Code is as follows:


// 4.1.1
// When it is used to determine whether an array has a length:
If (array. length> 0 )...

//... Use this method to determine the authenticity:
If (array. length )...

// 4.1.2
// When you only determine whether an array is null, use this parameter as opposed:
If (array. length = 0 )...

//... Use this method to determine the authenticity:
If (! Array. length )...

// 4.1.3
// When it is used to determine whether a string is null:
If (string! = "")...

//... Use this method to determine the authenticity:
If (string )...

// 4.1.4
// When you only judge whether a string is null:
If (string = "")...

//... Use this method to determine the authenticity:
If (! String )...

// 4.1.5
// When it is used to determine whether a reference is true:
If (foo = true )...

//... You only need to consider the benefits of built-in functions as you think:
If (foo )...

// 4.1.6
// When it is used to determine whether a reference is false:
If (foo = false )...

//... Use the exclamation mark to convert it to true
If (! Foo )...

//... Note that this will match 0, "", null, undefined, NaN
// If your _ required _ Is A boolean type of false, use the following command:
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,
// Relative to this:
If (foo = null | foo = undefined )...

//... Enjoy the benefits of forced conversion of = type, such:
If (foo = null )...

// Remember that 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 guide rather than a dogma.

The Code is as follows:


// 4.2.1
// Type conversion and Comparison

// The first time '=', '=' followed by (unless a loose type comparison is required)

// '=' Type conversion is not performed, which means:

"1" = 1;
// False

// '=' Converts 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

V. Practical Style

The Code is as follows:


// 5.1.1
// A practical Module

(Function (global ){
Var Module = (function (){

Var data = "secret ";

Return {
// This is a Boolean Value
Bool: true,
// A string
String: "a string ",
// An array
Array: [1, 2, 3, 4],
// An object
Object :{
Lang: "en-Us"
},
GetData: function (){
// Obtain the 'data' Value
Return data;
},
SetData: function (value ){
// Return the value of 'data' that has been assigned a value.
Return (data = value );
}
};
})();

// Others will appear here

// Turn your module into a Global Object
Global. Module = Module;

}) (This );

// 5.2.1
// A practical build Function

(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 );
};

// Do not use 'new' to call the build function. You may do this:
Var ctor = function (foo ){
Return new Ctor (foo );
};

// Convert our build function into a Global Object
Global. ctor = ctor;

}) (This );

Vi. Naming

A. You are not A meat Compiler/compressed, so try to become one.

The following code is a model of bad naming:

The Code is as follows:


// 6. A.1.1
// Sample code for poor naming

Function q (s ){
Return document. querySelectorAll (s );
}
Var I, a = [], els = q ("# foo ");
For (I = 0; I
There is no doubt that you have written such code-hopefully it will not appear from today.

Here is a piece of code with the same logic, but with more robust and appropriate naming (and a readable structure ):

The Code is as follows:


// 6. A.2.1
// Improved sample code for naming

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:

The Code is as follows:


// 6. A.3.1
// Name string

'Dog 'is a string

// 6. A.3.2
// Name arrays

'['Ogs']' is an array containing the 'dog string

// 6. A.3.3
// Name functions, objects, instances, and so on

CamlCase; function and var Declaration

// 6. A.3.4
// Name the builder, prototype, and so on

PascalCase; build a function

// 6. A.3.5
// Name the Regular Expression

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 the well-known call and apply, it is always preferred to select. bind (this) or a function is equivalent to it. Create a BoundFunction Declaration for subsequent calls. aliases are used only when there is no better choice.

The Code is as follows:


// 6. B .1
Function Device (opts ){

This. value = null;

// Create an asynchronous stream, which will be continuously called
Stream. read (opts. path, function (data ){

// Use stream to return the latest data value and update the Instance value
This. value = data;

}. Bind (this ));

// Control the frequency of event triggering
SetInterval (function (){

// Issue a controlled event
This. emit ("event ");

}. Bind (this), opts. freq | 100 );
}

// Assume that we have inherited the event sender (EventEmitter );)

When it cannot be run, functions equivalent to. bind are provided in most modern JavaScript libraries.

The Code is as follows:


// 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, create an alias for this, and use self as the identifier. This may cause bugs and should be avoided as much as possible.

The Code is as follows:


// 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 built-in a special thisArg tag and use it as much as possible.

The Code is as follows:


// 6. C.1

Var obj;

Obj = {f: "foo", B: "bar", q: "qux "};

Object. keys (obj). forEach (function (key ){

// | This | the current value is 'obj'

Console. log (this [key]);

}, Obj); // <-- the final parameter is 'thisarg'

// Print it out...

// "Foo"
// "Bar"
// "Qux"


ThisArg can be used in Array. prototype. every, Array. prototype. forEach, Array. prototype. some, Array. prototype. map, Array. prototype. filter.

VII. Misc

The ideas and concepts to be explained in this section are not dogmas. On the contrary, we encourage curiosity about existing practices to try a better solution to complete general JavaScript programming tasks.

A. Avoid using the switch. Modern method tracing will list functions with the switch expression as blacklists.

It seems that both Firefox and Chrome in the latest version have made significant improvements to switch statements. 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

The Code is as follows:


// 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 method that supports combination and reuse is to use an object to store "cases ",
// Use a function for delegation:

Var cases, delegator;

// The return value is for illustration only.
Cases = {
Alpha: function (){
// Statement
// Return Value
Return ["Alpha", arguments. length];
},
Beta: function (){
// Statement
// Return Value
Return ["Beta", arguments. length];
},
_ Default: function (){
// Statement
// Return Value
Return ["Default", arguments. length];
}
};

Delegator = function (){
Var args, key, delegate;

// Convert 'argument' to 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 an object
If (cases. hasOwnProperty (key )){
Delegate = cases [key];
}

// The arg scope can be set to a specific value,
// In this case, | null |
Return delegate. apply (null, args );
};

// 7. A.1.3
// Use the API in 7.a.1.2:

Delegator ("alpha", 1, 2, 3, 4, 5 );
// ["Alpha", 5]

// Of course, the value of the 'case' key can be easily changed to any value

Var caseKey, someUserInput;

// Is there a possible 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 this...

Delegator ();
// ["Default", 0]

B. return values in advance to improve code readability without too many performance differences

The Code is as follows:


// 7. B .1.1
// Poor:
Function returnLate (foo ){
Var ret;

If (foo ){
Ret = "foo ";
} Else {
Ret = "quux ";
}
Return ret;
}

// Good:

Function returnEarly (foo ){

If (foo ){
Return "foo ";
}
Return "quux ";
}

8. Native & Host Objects (Note: In fact, Host Objects should not be translated, but it is simply written in general books)

The most basic principle is:

Don't do anything stupid. Things will always get better.

To enhance this concept, please watch this demonstration:

"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

IX. Notes

The single line comment is the first choice in the code.
Multiple rows can also be used.
Line End comments should be avoided!
The JSDoc method is also good, but it takes a lot of time

10. Use a single language

No matter what language the program maintainer (or Team) specifies in which language the program should be written in the same language.

Appendix

Comma (Comma First)

All projects using this document as the basic style guide do not allow the code format of the pre-comma, unless explicitly specified or required by the author.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.