JavaScript Coding Specification (1)

Source: Internet
Author: User
Tags function definition logical operators version control system



Reference is the Baidu Company's JS specification, divided into two parts. This is the first part.
Recommendations JavaScript files use UTF-8 encoding without a BOM.


space [mandatory] the two-tuple operator must have a space on each side, and no spaces between the unary operator and the operand.
var a = !arr.length;a++;a = b + c;
[Force] must have a space before the opening curly brace {for the start of the code block.
// good
if (condition) {
}

while (condition) {
}

function funcName() {
}

// bad
if (condition){
}

while (condition){
}

function funcName(){
}
You must have a space after the [force] if/else/for/while/function/switch/do/try/catch/finally keyword.
// good
if (condition) {
}

while (condition) {
}

(function () {
})();

// bad
if(condition) {
}

while(condition) {
}

(function() {
})();
[Mandatory] When an object is created, there must be a space in the property after: No spaces are allowed before.
// good
var obj = {
    a: 1,
    b: 2,
    c: 3
};

// bad
var obj = {
    a : 1,
    b:2,
    c :3
};
[Mandatory] Function declaration, named function expression, function call, and (no spaces allowed between the functions).
// good
function funcName() {
}

var funcName = function funcName() {
};

funcName();

// bad
function funcName () {
}

var funcName = function funcName () {
};

funcName ();
[mandatory], and; No spaces are allowed before. If not at the end of the line, and; Must be followed by a space.
// good
callFunc(a, b);

// bad
callFunc(a , b) ;
[Force] In statements such as function calls, function declarations, bracket expressions, property accesses, If/for/while/switch/catch, and so on, () and [] do not allow spaces within the parentheses section.
// 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-- ) {
}
[Force] A single-line declaration of an array with an object, if the containing element, {}, and [] enclose the parentheses within the enclosing section is not allowed to contain spaces.


Explain:



Declares an array of elements and objects that are allowed to be written on one line only if the form of the inner element is simpler. The element is complex, or it should be written in a newline.


// 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};
newline [Force] each stand-alone statement must wrap at the end of the line. [Force] must not exceed 120 characters per line.


Explain:



Extra-long, indivisible code allows exceptions, such as complex regular expressions. Long strings are not in the exception column.


When the [force] operator wraps, the operator must be at the beginning of the new line.
// goodif (user.isAuthenticated()    && user.isInRole
// 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;
(‘admin‘) && user.hasAuthority(‘add-admin‘) || user.hasAuthority(‘delete-admin‘)) { // Code}var result = number1 + number2 + number3 + number4 + number5;// badif (user.isAuthenticated() && user.isInRole(‘admin‘) && user.hasAuthority(‘add-admin‘) || user.hasAuthority(‘delete-admin‘)) { // Code}var result = number1 + number2 + number3 + number4 + number5;
[Force] In a function declaration, function expression, function call, object creation, array creation, for statement and other scenarios, not allowed in, or; Front line break.
// 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
);
[Recommended] Sets of statements of different behaviors or logic, separated by blank lines, are easier to read.
// is just an example of logically wrapping, and does not represent the optimal implementation of setStyle
function setStyle (element, property, value) {
     if (element == null) {
         return;
     }

     element.style [property] = value;
}

[Recommended] When a statement has a length of more than 120, it is logically indented according to logical conditions.

// For more complicated logical condition combinations, place each condition on its own line, and place logical operators at the beginning of the line to separate them, or separate some logics by logical combinations.
// It is recommended to put the closing parenthesis) and the opening brace {on a separate line in the end, to ensure that the block inside the `if` can be easily visually recognized.
if (user.isAuthenticated ()
    && user.isInRole (‘admin’)
    && user.hasAuthority (‘add-admin’)
    || user.hasAuthority (‘delete-admin’)
) {
    // Code
}

// Truncate the string by a certain length and use the + operator for concatenation.
// Separate the strings as semantically as possible, such as not breaking in the middle of a complete noun.
// In particular, for the splicing of HTML fragments, the same structure as HTML is maintained by indentation.
var html = ‘‘ // use an empty string here so that the entire HTML fragment is strictly aligned on a new line
    + ‘<Article>’
    + ‘<H1> Title here </ h1>’
    + ‘<P> This is a paragraph </ p>’
    + ‘<Footer> Complete </ footer>’
    + ‘</ Article>’;

// You can also use arrays for splicing. It 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 parameters, write each parameter on a separate line, and put the closing right parenthesis) on a separate line.
// All parameters must be indented.
foo (
    aVeryVeryLongArgument,
    anotherVeryLongArgument,
    callback
);

// You can also combine parameters logically.
// The most classic is the baidu.format function. When calling, the parameters are divided into "template" and "data".
baidu.format (
    dateFormatTemplate,
    year, month, date, hour, minute, second
);

// When a function is called, if one or more parameters span multiple lines, each parameter should be on a separate line.
// This usually occurs when an anonymous function or object initialization is used as a parameter, such as the `setTimeout` function, etc.
setTimeout (
    function () {
        alert (‘hello’);
    },
    200
);

order.data.read (
    ‘Id =‘ + me.model.id,
    function (data) {
        me.attchToModel (data.result);
        callback ();
    },
    300
);

// Adjust the indentation when the chained call is long.
$ (‘# Items’)
    .find (‘. selected’)
    .highlight ()
    .end ();

// The ternary operator consists of 3 parts, so its line breaks should form different situations depending on the length of each part.
var result = thisIsAVeryVeryLongCondition
    ? resultA: resultB;

var result = condition
    ? thisIsAVeryVeryLongResult
    : resultB;

// Array and object initialization are mixed, strictly according to the style of each object `{` and end `}` in a separate line.
var array = [
    {
        // ...
    },
    {
        // ...
    }
];



statement [force] must not omit the semicolon at the end of the statement. [Force] In a if/else/for/do/while statement, even if there is only one row, you must not omit the block {...}.
// goodif (condition) {    callFunc();}// badif (condition) callFunc();if (condition)    callFunc();


The [force] function definition end does not allow the addition of semicolons.
// goodfunction funcName() {}// badfunction funcName() {};// If it is a function expression, semicolons are not allowed to be omitted。var funcName = function () {};


Force Iife must be added outside the function expression (, non-iife should not be added outside the function expression (.


Explain:





Iife = immediately-invoked Function Expression.





The extra (which allows the code to judge whether the function is called immediately at the beginning of the reading, and then the purpose of the next code.) Instead of dragging it to the bottom, it dawned.




// goodvar task = (function () {   // Code   return result;})();var func = function () {};// badvar task = function () {    // Code    return result;}();var func = (function () {});


Name the [force] variable using the Camel name method.
var loadingModules = {};


The [force] constant uses all uppercase letters, and the words are separated by an underscore.
var HTML_ENTITY = {};


The parameters of the [Force] function Use the Camel name method.
function hear(theBells) {}


The [mandatory] class uses the Pascal nomenclature.
function TextNode(options) {}


The method/property of the [force] class uses the Camel nomenclature.
function TextNode(value, engine) {    this.value = value;    this.engine = engine;}TextNode.prototype.clone = function () {    return this;};


The [force] enumeration variable uses the Pascal nomenclature, the attribute of the enumeration is capitalized with all letters, and the names are delimited by the underscore between the words.
var TargetState = {    READING: 1,    READED: 2,    APPLIED: 3,    READY: 4};


The [force] namespace uses the Camel name method.
equipments.heavyWeapons = {};


[Force] An abbreviation consisting of multiple words, in which the capitalization of all letters is consistent with the case of the first letter, depending on the current nomenclature and where it appears.
function XMLParser() {}function insertHTML(element, html) {}var httpRequest = new HTTPRequest();


The [force] class name uses nouns.
function Engine(options) {}


[Recommended] The function name uses the verb phrase.
function getStyle(element) {}


[Recommended] A variable of type Boolean starts with IS or has.
var isReady = false;var hasMoreCommands = false;


Recommendations The Promise object is expressed with the expression of the verb-Pentax phrase.
var loadingData = ajax.get(‘url‘);loadingData.then(callback);


Comment Line comment [mandatory] must have a single line. followed by a space, and the indentation is consistent with the code that is annotated by the next line. Multiline comments [recommended] Avoid using/.../Such a multiline comment. When there are multiple lines of comment content, multiple single-line comments are used. Document comments [mandatory] to facilitate code reading and self-documenting, the following must contain block comments in the form of/**...*/.
Explain:
File
Namespace
Class
Function or method
Class properties
Event
Global variables
Constant
AMD Modules

You must have a blank line before the [force] document comment. [Recommended] Self-documenting documentation describes what, rather than how. File comments [mandatory] The top of the file must contain a file comment, which identifies the file description with @file.

/** * @file Describe the file */


You can use @author to identify developer information in a file comment.


Explain:





Developer information can be a reflection of the developer's contribution to the file, and can help people who are having problems or want to know about the information to find a maintainer. Typically, a file is created with the creator identified. As the project progresses, more and more people join in the development of this document, and new authors should be added to the @author logo.





@author identity has multiple people, the principle is to sort by responsibility. Generally speaking, if there is a problem, it is better to find the first person than to find a second person. For example, the creator of the file for various reasons, the module handed over to other people or other teams, and later because of new requirements, others in the new code, add the @author identity should be added to the name of the creator in front of the person.





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





In a Business project, a file may be frequently modified by multiple people, and each person's maintenance time may not be very long, and it is not recommended to add @author identity to the file. Tracking changes through a version control system, determining the module's maintenance responsibility by business logic units, tracking and querying through documents and wikis, is a better way to manage responsibility.





@author identification should be used for technical infrastructure projects unrelated to business logic, especially open source public projects.




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


namespace annotations [recommended] namespaces use @namespace identity
/** * @namespace */var util = {};


Class Comment


Explain:





For constructors that are defined using the object constructor property, you can use the @constructor to mark the constructor.




/ **
  * Description
  *
  * @class
  * /
function Developer () {
     // constructor body
}


[Recommended] Use @extends to tag the inheritance information for a class.
/ **
  * Description
  *
  * @class
  * @extends Developer
  * /
function Fronteer () {
     Developer.call (this);
     // constructor body
}
util.inherits (Fronteer, Developer);


When you extend a class member by using the wrapper method, you must re-point through the @lends.


Explain:





A document that contains extension class members cannot be generated for this class without a @lends tag.




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

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


Member information such as properties or methods for a class is not public and should be used @protected or @private identity accessibility.


Explain:





The resulting document will have accessibility tags that prevent users from directly using properties or methods that are not public.




/ **
  * Class description
  *
  * @class
  * @extends Developer
  * /
var Fronteer = function () {
     Developer.call (this);

     / **
      * Property description
      *
      * @type {string}
      * @private
      * /
     this.level = ‘T12’;

     // constructor body
};
util.inherits (Fronteer, Developer);

/ **
  * Method description
  *
  * @private
  * @return {string} return value description
  * /
Fronteer.prototype.getLevel = function () {
};


function/method comments [Mandatory] Function/method comments must contain function descriptions, with parameters and return values that must be identified with a comment.


Explain:





When the return keyword is used only as an Exit Function/method, there is no need to annotate the return value.



The [force] parameter and the return value comment must contain type information and do not allow the description of the parameter to be omitted. [Recommended] The @inner identity can be used when the function is an intrinsic function and cannot be accessed externally.
/ **
  * Function description
  *
  * @param {string} p1 Description of parameter 1
  * @param {string} p2 The description of parameter 2 is relatively long
  * Then wrap.
  * @param {number =} p3 description of parameter 3 (optional)
  * @return {Object} return value description
  * /
function foo (p1, p2, p3) {
     var p3 = p3 || 10;
     return {
         p1: p1,
         p2: p2,
         p3: p3
     };
}


[Force] The description of the items in Object must use the @param identity.
/ **
  * Function description
  *
  * @param {Object} option parameter description
  * @param {string} option.url option description
  * @param {string =} option.method option description, optional parameters
  * /
function foo (option) {
     // TODO
}


The event comment [Force] must use @event to identify the event, and the identity of the event argument is the same as the parameter identification of the method description.
/ **
  * Triggered when the value changes
  *
  * @event Select # change
  * @param {Object} e e
  * @param {string} e.before before
  * @param {string} e.after after
  * /
this.fire (
     ‘Change’,
     {
         before: ‘foo’,
         after: ‘bar’
     }
);


[Force] Use @fires to identify the broadcast event before the function that broadcasts the event, and use the @event to identify the event before broadcasting the event code. [Recommended] For comments on event objects, use @param identification, which is more readable when generating documents.
/ **
  * Click processing
  *
  * @fires Select # change
  * @private
  * /
Select.prototype.clickHandler = function () {

     / **
      * Triggered when the value changes
      *
      * @event Select # change
      * @param {Object} e e
      * @param {string} e.before before
      * @param {string} e.after after
      * /
     this.fire (
         ‘Change’,
         {
             before: ‘foo’,
             after: ‘bar’
         }
     );
};


Constant comment [mandatory] constants must use @const tags and contain description and type information.
/ **
  * Constant description
  *
  * @const
  * @type {string}
  * /
var REQUEST_URL = ‘myurl.do’;


Complex type annotations [recommended] for annotations of complex structures that are not defined by a type, you can use the @typedef identity to define them.
// `namespaceA ~` can be replaced with other namepaths prefixes, in order to generate documents that can display the types and links defined by `@ typedef`.
/ **
  * Server
  *
  * @typedef {Object} namespaceA ~ Server
  * @property {string} host
  * @property {number} port
  * /

/ **
  * server list
  *
  * @type {Array. <namespaceA ~ Server>}
  * /
var servers = [
     {
         host: ‘1.2.3.4’,
         port: 8080
     },
     {
         host: ‘1.2.3.5’,
         port: 8081
     }
];


AMD module comments [Force] AMD modules use @module or @exports identification.


Explain:





@exports and @module can be used to identify the module, except that @module can omit the module name. You can omit the module: prefix in namepaths when using only @exports.




define(
    function (require) {

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

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

        return foo;

    }
);





You can also use the @module identifier before the exports variable:




define(
    function (require) {

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


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

        return exports;
    }
);





If you use factory's exports parameter directly, you can also:




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

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



[Mandatory] for references that have been identified as AMD modules using @module, the module: prefix must be added to the namepaths.


Explain:





Namepaths No module: prefixes, links will not be generated correctly in the generated document.




/ **
  * Click processing
  *
  * @fires module: Select # change
  * @private
  * /
Select.prototype.clickHandler = function () {
     / **
      * Triggered when the value changes
      *
      * @event module: Select # change
      * @param {Object} e e
      * @param {string} e.before before
      * @param {string} e.after after
      * /
     this.fire (
         ‘Change’,
         {
             before: ‘foo’,
             after: ‘bar’
         }
     );
};


[Recommended] For a class-defined module, you can use @alias to identify the build function.
/**
 * A module representing a jacket.
 * @module jacket
 */
define(
    function () {

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

        return Jacket;
    }
);



When a multi-module definition is recommended, you can use @exports to identify each module.
// one module
define(‘html/utils‘,
    /**
     * Utility functions to ease working with DOM elements.
     * @exports html/utils
     */
    function () {
        var exports = {
        };

        return exports;
    }
);

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

        return exports;
    }
);



[Recommended] For a module exports to Object, you can use the @namespace identity.


Explain:





References to modules can omit the module: prefix when using @namespace instead of @module or @exports.



[Recommended] For modules that have exports as class names, use @class and @exports identities.
// When only using @class Bar, class methods and properties must be added with @name Bar # methodName to identify them. Cooperating with @exports can avoid this trouble, and the module: prefix can be omitted when referring.
// Also note that the class name needs 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
};


Detail Notes


For internal implementations, logical explanations that are not easy to understand, summary information, and so on, we may need to write detailed comments.



The [recommended] Details note follows the format of a single-line comment. Indicates that each row is the start of a single-line comment when it must be wrapped.
function foo (p1, p2, opt_p3) {
     // Here is a description of the specific internal logic
     // Description is too long and needs a line break
     for (...) {
         ....
     }



[Mandatory] Sometimes we use some special tags to illustrate. Special tokens must be in the form of a single-line comment. Some common tags are listed below:
TODO: There are functions to be implemented. At this point, you need to make a brief description of the functionality that will be implemented.
Fixme: The code is running fine, but it may need to be fixed due to time or other reasons. A brief description of how to fix it is required at this point.
HACK: A code that is not well written to fix certain problems or that uses some strange means. At this point you need to describe the idea or the strange means.
XXX: There are traps in this place. The trap needs to be described at this time.


JavaScript Coding Specification (1)


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.