Volt MX Application Design and Development Guidelines: Application Development Guidelines > Coding Standards
Coding Standards
-
JavaScript is case sensitive.
- Do not use JavaScript reserved keywords for variable names.
-
Properties and methods:
-
Private properties, variables, and methods (in files or classes) should be named with a trailing underscore.
-
Protected properties, variables, and methods should be named without a trailing underscore (like public ones).
-
- Method and function parameters:
- Optional function arguments start with opt_.
- Functions that take a variable number of arguments should have the last argument named var_args. You may not refer to var_args in the code; use the arguments array.
- Optional and variable arguments can also be specified in @param annotations. Although either convention is acceptable to the compiler, using both together is preferred.
- Getters and Setters
- Getters and Setters for properties are discouraged. However, if they are used, then getters must not change observable state.
- Accessory functions
- Getters and setters methods for properties are not required. However, if they are used, then getters must be named getFoo() and setters must be named setFoo(value). (For Boolean getters, isFoo() is also acceptable, and often sounds more natural.)
-
Namespaces
-
JavaScript has no inherent packaging or name-spacing support.
-
Global name conflicts are difficult to debug, and can cause intractable problems when two projects try to integrate. In order to make it possible to share common JavaScript code, we’ve adopted conventions to prevent collisions.
-
- Use namespaces for global code
- Always prefix identifiers in the global scope with a unique pseudo namespace related to the project or library. If you are working on “Project Sloth”, a reasonable pseudo namespace would be sloth.*.
Many JavaScript libraries, including the Closure library and Dojo toolkit give you high-level functions for declaring your namespaces. Be consistent about how you declare your namespaces.
- Respect namespace ownership
- When choosing a child-namespace, make sure that the owners of the parent namespace know what you are doing. If you start a project that creates hats for sloths, make sure that the Sloth team knows that you’re using sloth.hats.
-
Use different namespaces for external code and internal code
-
External code is the code that comes from outside your codebase, and is compiled independently.
-
Internal and external names should be kept strictly separate. If you’re using an external library that makes things available in foo.hats.*, your internal code should not define all its symbols in foo.hats.*.
-
-
If you need to define new APIs on an external namespace, you should explicitly export the public API functions, and only those functions.
- Your internal code should call the internal APIs by their internal names, for consistency and so that the compiler can optimize them better.
-
Use different namespaces for external code and internal code
-
External code is the code that comes from outside your codebase, and is compiled independently.
-
Internal and external names should be kept strictly separate. If you’re using an external library that makes things available in foo.hats.*, your internal code should not define all its symbols in foo.hats.*.
-
-
If you need to define new APIs on an external namespace, you should explicitly export the public API functions, and only those functions.
- Your internal code should call the internal APIs by their internal names, for consistency and so that the compiler can optimize them better.
-
Alias long type names to improve readability
- Use local aliases for fully-qualified types if doing so improves readability. The name of a local alias should match the last part of the type.
* Do not alias namespaces.
* Never create aliases in the global scope. Use them only in function blocks. * Alias long type names to improve readability
* Use local aliases for fully-qualified types if doing so improves readability. The name of a local alias should match the last part of the type.
* Do not alias namespaces.
* Never create aliases in the global scope. Use them only in function blocks. * Alias long type names to improve readability
* Use local aliases for fully-qualified types if doing so improves readability. The name of a local alias should match the last part of the type.
* Do not alias namespaces.
* Never create aliases in the global scope. Use them only in function blocks.
Usage of Global and Local Variables
- A variable declared (using var) within a JavaScript function becomes local and can only be accessed from within that function.
- If you fail to specify “var”, the variable gets placed in the global context, potentially clobbering existing values. Also, if there is no declaration, it is hard to tell in what scope a variable lives (for example: It could be in the Document or Window just as easily as in the local scope). So always declare with “var”.
- Use locals rather than globals whenever possible.
- Global variables have application scope and they are not garbage collected unless explicitly cleared or application exits. Set global variables to null after the usage is completed (equivalent to “null” in Java)
-
Widgets have a lot of metadata associated with them and consume a lot more memory to hold the same amount of data than a global variable.
-
For example, voltmx.store.setItem and voltmx.store.getItem result in disk I/O and definitely has much more performance impact than accessing an in memory variable.
-
Do not use setItem / getItem or hidden widgets as replacement for global variables.
-
-
Define all the global variables using the global variables section of services tab so that it is easier to keep a track of them.
-
If you want to read a key from a JSON object more than once, it is better to read that key in a local variable then use it.
-
Have a look at the following code snippet:
-
File Names
The following file naming conventions must be followed as best practices:
- File names should be all lowercase in order to avoid confusion on case-sensitive platforms.
- File names should end in .js, and should contain no punctuation except for - or _ (prefer - to _).
Readability
- Use Javadoc-like style for commenting.
- Provide a comment whenever a construct ends.
- Use proper indentation for debugging.
- Use tab indentation for logical blocks.
- Write proper documentation and comments for each function/module and for typical logic in functions
- All wrapped lines must be indented either left to the expression or above or indented four spaces, except for array and object initializations and passing anonymous functions.
Note: Two space indentation must not be used.
Common mistakes
Following is a list of common mistakes to take care of:
- Do not have cyclic references between JSON objects (Two JSON objects having reference to each other) as it makes garbage collection difficult.
- Perform checks for null (for example: variables, mapping segment data etc) and empty string always before doing any operation on any user input data. This ensures that unexpected results / app crashes are avoided.
- Do not just define strings to null. Initialize strings to either “ or ‘’. If you initialize strings to null, JavaScript will treat it as string value “null” and all the operations performed on this variable will get effected.
- When validating the input, be careful with blank spaces and trim the string.
**Better approach**: _voltmx.string.trim()_ will delete the leading and trailing blank spaces of the string.
- Have a look at this code snippet:
**Better Approach**: For improving the readability and code compactness, you can write the above code as a lengthy one. Following is an example of lengthy code:
- If the function returns a value, do not have multiple return statements. Instead, build logic in such a way that you have only one return at the end of the function.
- If you are calling voltmx.os.toNumber(), ensure that the string you are passing to the function is a number string that is “5”, “3443”. Else you will get run-time exceptions.
- Best practice: To avoid run-time exceptions, always use the logic as explained in the following code:
- Avoid writing code outside function blocks. Since Volt MX platform does not guarantee a specific order of loading JavaScript files, code written outside function blocks can lead to undefined errors.
- Write code in function blocks and invoke the same through one of the application initialization callbacks (preappinit , appinit etc).
- The name of the form and the module file should not be the same. Since all the files are flattened when packed into a deployable binary, name clashes should be avoided.
General Guidelines
The following general guidelines must be followed as best practices:
-
Write logically related functions (functions related to a specific functionality) within a single module. For example, write all the account summary related functions within accSummary.lua or accSummary.js module.
-
Do the necessary validations in Lua JavaScript before making network calls. For example, check if the text box has data before invoking a service.
-
Avoid code duplication by writing reusable functions which can be shared across modules/applications.
-
Write smaller functions (maximum with hundred lines of code) instead of huge monolithic spaghetti code.
-
Write generalized functions for the tasks that are repetitive across the application.
-
Avoid function calls or expressions (which give the same value in the loops) as these will slow down the loop.
- As a good practice, keep the name of input and output variables in either lowercase or uppercase. Do not mix both the cases. As Lua JavaScript are case sensitive, this helps in making the development easy and also minimizes the errors.