2 Code Style

2.1 file

[Suggestion] Use UTF-8 encoding without BOM for JavaScript files.

Explanation:

Utf-8 encoding has wider adaptability. BOM can cause unnecessary interference when using programs or tools to process documents.

[Suggestion] Leave a blank line at the end of the file.

2.2 structure

2.2.1 the indentation

[Force] Use 2 Spaces as an indentation level. No more than 2 Spaces or TAB characters are allowed.

[Mandatory] Case and default under switch must have an indent level added.

Example:

// good
switch (variable) {

    case '1':
        // do...
        break;

    case '2':
        // do...
        break;

    default:
        // do...

}

// bad
switch (variable) {

case '1':
    // do...
    break;

case '2':
    // do...
    break;

default:
    // do...

}
Copy the code

2.2.2 Spaces

Binary operators must have a space on either side. Unary operators are not allowed to have a space between the operator and the object.

Example:

var a = ! arr.length; a++; a = b + c; [Force] Used as the opening curly brace {at the beginning of a code block must be preceded by a space. Example: // goodif (condition) {
}

while (condition) {
}

function funcName() {
}

// bad
if (condition){
}

while (condition){
}

function funcName(){
}
Copy the code

[Force] if/else/for/while/function/switch/do/try/catch/finally

The keyword must be followed by a space.

Example:

// good
if (condition) {
}

while (condition) {
}

(function () {
})();

// bad
if(condition) {
}

while(condition) {
}

(function() {
})();
Copy the code

[Mandatory] When an object is created, : must be followed by a space, and: cannot be preceded by a space.

Example:

// good
var obj = {
    a: 1,
    b: 2,
    c: 3
};

// bad
var obj = {
    a : 1,
    b:2,
    c :3
};
Copy the code

No Spaces between function names and () are allowed in function declarations, named function expressions, and function calls.

Example:

// good
function funcName() {
}

var funcName = function funcName() {}; funcName(); // badfunction funcName () {
}

var funcName = function funcName() {}; funcName ();Copy the code

[Mandatory], must be preceded by Spaces and. Spaces are not allowed after.

Example:

// good
callFunc(a , b);

// bad
callFunc(a,b) ;
Copy the code

In function calls, function declarations, parenthesis expressions, attribute access, if/for/while/switch/catch, etc., Spaces within () and [] are not allowed next to parentheses.

Example:

// good

callFunc(param1, param2, param3);

save(this.list[this.indexes[i]]);

needIncream && (variable += increament);

if (num > list.length) {
}

while (len--) {
}


// bad

callFunc( param1, param2, param3 );

save( this.list[ this.indexes[ i ] ] );

needIncreament && ( variable += increament );

if ( num > list.length ) {
}

while ( len-- ) {
}
Copy the code

[enforces] single-line declared arrays and objects. If they contain elements, {} and [] do not allow Spaces within the parentheses.

Explanation:

Declare arrays and objects that contain elements. Write on a single line only if the internal elements are simple. If the element is complex, you should write on a new line.

Example:

// good
var arr1 = [];
var arr2 = [1 , 2 , 3];
var obj1 = {};
var obj2 = {name: 'obj'};
var obj3 = {
    name: 'obj',
    age: 20,
    sex: 1
};

// bad
var arr1 = [ ];
var arr2 = [ 1, 2, 3 ];
var obj1 = { };
var obj2 = { name: 'obj' };
var obj3 = {name: 'obj', age: 20, sex: 1};
Copy the code

No extra space at the end of a line.

2.2.3 newline

[Mandatory] Line breaks must follow the end of each independent statement. Each line contains a maximum of 120 characters.

Explanation:

Extremely long, indivisible code allows exceptions, such as complex regular expressions. Long strings are not an exception.

When the operator is newline, the operator must be at the beginning of the new line.

Example:

// good
if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
    || user.hasAuthority('delete-admin')
) {
    // Code
}

var result = number1 + number2 + number3
    + number4 + number5;


// bad
if (user.isAuthenticated() &&
    user.isInRole('admin') &&
    user.hasAuthority('add-admin') ||
    user.hasAuthority('delete-admin')) {
    // Code
}

var result = number1 + number2 + number3 +
    number4 + number5;
Copy the code

In function declaration, function expression, function call, object creation, array creation, for statement, etc., cannot be in, or; Before the line break.

Example:

// good
var obj = {
    a: 1,
    b: 2,
    c: 3
};

foo(
    aVeryVeryLongArgument,
    anotherVeryLongArgument,
    callback
);


// bad
var obj = {
    a: 1
    , b: 2
    , c: 3
};

foo(
    aVeryVeryLongArgument
    , anotherVeryLongArgument
    , callback
);
Copy the code

[Suggestion] A set of statements with different behaviors or logic, separated by blank lines, is easier to read.

Example:

// This is only an example of a logical line breaksetOptimal implementation of Stylefunction setStyle(element, property, value) {
    if (element == null) {
        return;
    }

    element.style[property] = value;
}
Copy the code

[Suggestion] When the line length of a statement exceeds 120, indent the statement according to logical conditions.

Example:

// For more complex combinations of logical conditions, separate each condition on a single line, place the logical operator at the beginning of the line for separation, or separate part of the logic according to the logical combination. // It is recommended to finally put the close parenthesis) and the left curly brace {on a separate line, ensuring that 'if'block can be easily identified visually.if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
    || user.hasAuthority('delete-admin') {// Code} // truncate the string by a certain length and concatenate it with the + operator. // Separate strings as semantically as possible, such as not breaking in the middle of a complete noun. // In particular, HTML fragments are concatenated to keep the same structure as HTML. var html =' '// An empty string is used here so that the entire HTML fragment is strictly aligned + on the new line'<article>'
    +     '<h1>Title here</h1>'
    +     '<p>This is a paragraph</p>'
    +     '<footer>Complete</footer>'
    + '</article>'; // Arrays can also be used for concatenation, which is easier to adjust the indentation than '+'. var html = ['<article>'.'<h1>Title here</h1>'.'<p>This is a paragraph</p>'.'<footer>Complete</footer>'.'</article>'
];
html = html.join(' '); // When there are too many arguments, write each argument on its own line, and separate the closing parenthesis) on its own line. // All parameters must be indent. foo( aVeryVeryLongArgument, anotherVeryLongArgument, callback ); // Arguments can also be combined logically. // Bidu. Format function, bidu. Format function Format (DateFormatte at the templatte, Year, Month, Date, Hour, minute, second); // When a function is called, if one or more arguments span multiple lines, each argument should have its own line. // This usually occurs when an anonymous function or object is initialized as an argument, such as'setTimeout 'function, etc.setTimeout(
    function () {
        alert('hello'); }, 200); order.data.read('id=' + me.model.id,
    function(data) { me.attchToModel(data.result); callback(); }, 300); // Use indentation for longer chain calls. $('#items')
    .find('.selected') .highlight() .end(); // The ternary operator is made up of three parts, so newlines should behave differently depending on the length of each part. var result = thisIsAVeryVeryLongCondition ? resultA : resultB; var result = condition ? thisIsAVeryVeryLongResult : resultB; // Mix array and object initialization, strictly following the style of each object '{' and end'} 'on a separate line. var array = [ { // ... }, { // ... } ];Copy the code

[Suggestion] For if… else… , try… catch… It is recommended to add a line break after the} sign to make the code hierarchy clearer and easier to read.

Example:

if (condition) {
    // some statements;
}
else {
    // some statements;
}

try {
    // some statements;
}
catch (ex) {
    // some statements;
}
Copy the code

2.2.4 statement

[Mandatory] Do not omit the semicolon at the end of a statement.

If/else/for/do/while statements do not omit the block {… }.

Example:

// good
if (condition) {
    callFunc();
}

// bad
if (condition) callFunc();
if (condition)
    callFunc();
Copy the code

To add a semicolon at the end of a function definition.

Example:

// good
function funcName() {}; // badfunction funcName() {} // In the case of function expressions, semicolons are not allowed to be omitted. var funcName =function() {};Copy the code

**[enforces] IIFE must be added outside of a function expression. Non-iife cannot be added outside of a function expression. **

Explanation:

IIFE = Immediately-Invoked Function Expression.

Extra (allows the code to determine at the beginning of the reading whether a function is called immediately, and hence what the following code is for. Instead of dragging it all the way to the bottom.

Example:

// good
var task = (function () {
   // Code
   returnresult; }) (); var func =function() {}; // bad var task =function () {
    // Code
    returnresult; } (); var func = (function() {});Copy the code

2.3 named

[Force] Variables to use Camel nomenclature.

Example:

var loadingModules = {};

[Mandatory] Names of constants with all uppercase letters and underscores between words.

Example:

var HTML_ENTITY = {};

[Enforces] Use Camel naming for functions.

Example:

function stringFormat(source) { }

[enforces] Use Camel nomenclature for the parameters of the function.

Example:

function hear(theBells) { }

Enforce Pascal naming for classes.

Example:

function TextNode(options) { }

[Enforces] Use Camel nomenclature for methods/attributes of classes.

Example:

function TextNode(value, engine) {
    this.value = value;
    this.engine = engine;
}

TextNode.prototype.clone = function () {
    return this;
};
Copy the code

[Mandatory] Enumeration variables are named using Pascal nomenclature. Enumeration properties are named using all uppercase letters and underscore separated words.

Example:

var TargetState = { READING: 1, READED: 2, APPLIED: 3, READY: 4 };

[Enforces] Use Camel for namespaces.

Example:

equipments.heavyWeapons = {};

[Mandatory] A multi-word abbreviation in which the case of all letters is the same as the case of the first letter, based on the current nomenclature and the position in which it occurs.

Example:

function XMLParser() { }

function insertHTML(element, html) { }

var httpRequest = new HTTPRequest();

Class names use nouns.

Example:

function Engine(options) { }

[Suggestion] Use verb-object phrases for function names.

Example:

function getStyle(element) { }

[Suggestion] Boolean variables start with is or has.

Example:

var isReady = false; var hasMoreCommands = false;

[误] I Promise you I’ll make a Promise.

Example:

var loadingData = ajax.get(‘url’); loadingData.then(callback);

2.4 annotations

2.4.1 Single-line comments

Mandatory The row must be exclusive. // Followed by a space, indented to match the next line of commented code.

2.4.2 Multi-line comments

Avoid using /./ Multiline comments like this. Use multiple single-line comments when you have multi-line comment content.

2.4.3 Documented comments

[Mandatory] For easy code reading and self-documentation, the following content must be included with /… */ block comments in the form. **

Explanation:

File Namespace Class function or method Class attribute Event global variable constant AMD module

[Mandatory] A line must be left blank before a comment.

[Suggestion] Self-documented documents say what, not how.

2.4.4 Type Definition

Type definitions all start with {and end with}.

Explanation:

Common types are as follows:

{string}, {number}, {Boolean}, {Object}, {Function}, {RegExp}, {Array}, {Date}.

Types are not limited to built-in types, but can also be custom types. For example, a class is defined

Developer, you can use it to define the type of a parameter and return value.

[Mandatory] For basic types {string}, {number}, {Boolean}, the first letter must be lowercase.

Type definition syntax example explanation

String {string} —

Number {number} —

Boolean {boolean} —

Object {Object} —

Function {Function} —

RegExp {RegExp} —

Array {Array} —

Date {Date} —

{Array.} Array of multiple types {(number | Boolean)} may be number or Boolean. Null {? Number} may be either number or NULL. Null {! Function (number, Boolean) {Function (number, Boolean) {Function (number, Boolean)}

Boolean):string} function, parameter, return type Promise Promise. Error returned by failure Type Parameter Optional @param {string=} NAME This parameter is optional. = is a variable type parameter @param {… Number} args variable length parameter,… Any type {} Any type Optional Any type @param {=} NAME This parameter is optional. The type is unlimited. *} args Variable length parameter, the type is not limited. 2.4.5 File Comments [Mandatory] The top of a file must contain a file comment, identified by @file. Example:
,>

/**
 * @file Describe the file
 */
Copy the code

[Suggestion] You can use @author to identify the developer information in the file comments.

Explanation:

Developer information reflects the developer’s contribution to the document and can be directed to the maintainer by people who have problems or want to know more about it. Typically, files are created with the identity of the creator. As the project progresses and more people participate in the development of this file, new authors should be added to the @author identifier.

When @author identifies multiple people, the principle is to sort by responsibility. Usually if there’s a problem, it’s better to go to the first person than to go to the second person. For example, the author of a file for some reason, the module is handed over to someone else or another team, and later, because of new requirements, someone else should add their own name before the author when adding new code.

Names in @author are not allowed to be deleted. The fruits of any labor should be respected.

In a business project, a file may be frequently modified by multiple people, and the maintenance time of each person may not be long. Therefore, it is not recommended to add the @author identifier to a file. Better accountability management is to track changes through version control systems, identify maintenance responsibilities for modules by business logic units, and track and query through documentation and wikis.

For technical infrastructure projects that are business logic-neutral, especially open source public projects, the @author identifier should be used.

Example:

/**
 * @file Describe the file
 * @author author-name([email protected])
 *         author-name2([email protected])
 */
Copy the code

2.4.6 Namespace Comments

[Suggestion] Use @namespace to identify the namespace.

Example:

/**
 * @namespace
 */
var util = {};
Copy the code

2.4.7 class annotation

Use @class to tag a class or constructor.

Explanation:

Constructors defined using the object constructor property can be marked with @constructor.

Example:

/** ** description ** @class */function Developer() {
    // constructor body
}
Copy the code

Suggestion: Use @extends to mark the inheritance information of a class.

Example:

/** * Description ** @class * @extends Developer */function Fronteer() {
    Developer.call(this);
    // constructor body
}
util.inherits(Fronteer, Developer);
Copy the code

Lendings When you expand the members of a class using the wrapper method, you must redirect the endings through the @lendings.

Explanation:

The document that contains the members of the extended class cannot be generated for the class without the @lendings tag.

Example:

/** * Class description ** @class * @extends Developer */function Fronteer() {
    Developer.call(this);
    // constructor body
}

util.extend(
    Fronteer.prototype,
    /** @lends Fronteer.prototype */{
        getLevel: function () {
            // TODO
        }
    }
);
Copy the code

Member information about a class, such as attributes or methods, is not public. Instead, use @protected or @private to indicate accessibility.

Explanation:

The generated document will be marked for accessibility, preventing users from directly using non-public properties or methods.

Example:

/** * class description ** @class * @extends Developer */ var Fronteer =function() { Developer.call(this); /** * Attribute description ** @type {string}
     * @private
     */
    this.level = 'T12'; // constructor body }; util.inherits(Fronteer, Developer); /** * method description ** @private * @return{string}. The return value description * / Fronteer prototype. GetLevel =function() {};Copy the code

2.4.8 Function/method comments

Mandatory function/method comments must contain function descriptions and must be identified by comments if they have arguments and return values.

Explanation:

When the return keyword is used only as an exit function/method, you do not need to comment on the return value.

Parameter and return value comments must contain type information, and parameter descriptions are not allowed to be omitted.

Suggestion: If a function is internal and cannot be accessed from outside, use @inner.

Example:

@param {number=} @param {number=} @param {number=} @param {number=} @param {number=} @param {number=} @param {number=} @param {number=} @param {number=} @param {number=} @param {number=returnObject} Return value Description */function foo(p1, p2, p3) {
    var p3 = p3 || 10;
    return {
        p1: p1,
        p2: p2,
        p3: p3
    };
}
Copy the code

[Mandatory] The @param identifier must be used to describe items in Object.

Example:

/** * Function description ** @param {Object} option Parameter Description * @param {string} option.url Option item description * @param {string=} option.method Option Specifies the option. */ is optionalfunction foo(option) {
    // TODO
}
Copy the code

[Suggestion] When overriding a parent class method, add the @override flag. If the number, type, order, and return value type of the overridden parameters are not changed, @param and @return can be omitted and only marked by @override. Otherwise, a complete comment should still be made.

Explanation:

In short, a subclass can omit comments on arguments and return values when it overrides a method that uses the parent class’s method comments directly.

2.4.9 Event Comments

[Mandatory] @event must be used to identify events. The identifiers of event parameters are the same as those in the method description. Example:

/** * @event Select is triggered when the value changes#change* @param {Object} e e description * @param {string} e.before before Description * @param {string} e.after after description */ this.fire('change',
    {
        before: 'foo',
        after: 'bar'});Copy the code

[Mandatory] Use @Fires before functions that broadcast events and @event before event codes to identify events.

[Suggestion] For comments on event objects, use @param to make the generated document more readable.

Example:

Fires Select ** @Fire Protection Engineers Select#change
 * @private
 */
Select.prototype.clickHandler = function() {/** * @event Select is triggered when the value changes#change* @param {Object} e e description * @param {string} e.before before Description * @param {string} e.after after description */ this.fire('change',
        {
            before: 'foo',
            after: 'bar'}); };Copy the code

2.4.10 Constant comments

Constants must use the @const tag and contain description and type information.

Example:

/** ** Constant description ** @const * @type {string}
 */
var REQUEST_URL = 'myurl.do';
Copy the code

2.4.11 Annotation of complex types

[Suggestion] For comments of complex structures whose type is not defined, you can use the @typedef identifier to define them.

Example:

// 'namespaceA~' can be replaced with other namepaths in order to generate the types and links defined by @typedef in the document. /** * Server ** @typedef {Object} namespaceA~Server * @property {string} host host * @property {number} port Port */ /** ** Server list * * @type {Array.<namespaceA~Server>}
 */
var servers = [
    {
        host: '2.',
        port: 8080
    },
    {
        host: '1.2.3.5',
        port: 8081
    }
];
Copy the code

2.4.12 COMMENTS on AMD Modules

AMD modules use @Module or @exports logo.

Explanation:

@exports and @Module can both be used to identify modules. The difference is that @module can omit the module name.

You can omit the module: prefix in namepaths if you only use @exports.

Example:

define(
    function (require) {

        /**
         * foo description
         *
         * @exports Foo
         */
        var foo = {
            // TODO
        };

        /**
         * baz description
         *
         * @return {boolean} return description
         */
        foo.baz = function () {
            // TODO
        };

        returnfoo; }); You can also use @Module before exports variables: define(function (require) {

        /**
         * module description.
         *
         * @module foo
         */
        var exports = {};


        /**
         * bar description
         *
         */
        exports.bar = function () {
            // TODO
        };

        returnexports; }); /** * module description. ** @module */ define()function (require, exports) {

        /**
         * bar description
         *
         */
        exports.bar = function () {
            // TODO
        };
        returnexports; });Copy the code

[Mandatory] Module: must be prefixed with @ Module in namepaths for AMD module references.

Explanation:

If the Namepaths do not have the Module: prefix, the generated documents will not generate links correctly.

Example:

Fires Module :Select ** @Fires Module :Select#change
 * @private
 */
Select.prototype.clickHandler = function() {/** * @event Module :Select#change* @param {Object} e e description * @param {string} e.before before Description * @param {string} e.after after description */ this.fire('change',
        {
            before: 'foo',
            after: 'bar'}); };Copy the code

[Suggestion] For class-defined modules, you can use @alias to identify the constructor function.

Example:

/**
 * A module representing a jacket.
 * @module jacket
 */
define(
    function () {

        /**
         * @class
         * @alias module:jacket
         */
        var Jacket = function() {};returnJacket; });Copy the code

[Suggestion] If multiple modules are defined, @exports can be used to identify each module.

Example:

// one module
define('html/utils',
    /**
     * Utility functions to ease working with DOM elements.
     * @exports html/utils
     */
    function () {
        var exports = {
        };

        returnexports; }); // another module define('tag',
    /** @exports tag */
    function () {
        var exports = {
        };

        returnexports; });Copy the code

Suggestion: For the module whose exports are Object, you can use @namespace.

Explanation:

Module references can omit the module: prefix when using @namespace instead of @module or @exports.

[Suggestion] For modules whose class name is exports, use the @class and @exports identifiers.

Example:

// When only @class Bar is used, @name Bar must be added to class methods and attributes#methodName, which works with @exports to get rid of this problem and omit the module: prefix when referencing.// Also note that class names need to be defined using var. /** * Bar description * * @see foo * @exports Bar * @class */ var Bar =function () {
    // TODO
};

/**
 * baz description
 *
 * @return {(string|Array)} return description
 */
Bar.prototype.baz = function () {
    // TODO
};
Copy the code

2.4.13 Detailed comments

For internal implementations, difficult logic instructions, summary information, and so on, we may need to write detailed annotations.

[Suggestion] Follow the format of a single line comment. Specifies that when line breaks are required, each line is the start of a single-line comment.

Example:

functionFoo (p1, p2, opt_p3) {foo(p1, p2, opt_p3)for(...). {... }}Copy the code

[Mandatory] Sometimes we use special tokens to illustrate. Special tags must be in the form of a single-line comment. Here are some common tags:

Explanation:

TODO: Features waiting to be implemented. In this case, a brief description of the functions to be implemented is required. FIXME: This code runs fine, but may need to be fixed due to time constraints or other reasons. A brief explanation of how to fix it is needed. HACK: code that is poorly written to fix a problem or uses some weird trick. A description of the train of thought or the strange method is needed. XXX: There is a trap. The trap needs to be described.