#summary One-sentence summary of this page. = Contributing to test framework = You can contribute to opensocial test framework by sending in the patch to opensocial-and-gadgets-spec@googlegroups.com. For most part, Javascript style follow [http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html Java Style], but very in several key places. = Javascript Coding Style Guide = == for in loops == Always include hasOwnProperty tests. You may deviate from the bracing rules for this one case, as in: {{{ for (var name in object) if (object.hasOwnProperty(name)) { // code goes here } }}} *Reasoning:* Any modifications to Object.prototype will result in those properties showing up as iterable properties. == Dictionaries / Maps / Associative Arrays. == Always use raw primitive objects ({}). *Reasoning:* Memory consumption, clarity, consistency. Arrays Always use the array literal constructor [], unless creating an empty array with pre-allocated size for some reason. *Reasoning:* The array constructor is overloaded, and passing a single argument yields an empty array of length n rather than a single-element array containing n. == Blocks == Javascript does not support any block scope other than function level. Because of this, you should actually declare variables as close to the top of the function as possible rather than within the block. Consider this: {{{ for (var i = 0; i < 10; ++i) { var foo; if (i === 1) { foo = "hello"; } document.write(foo); } }}} This actually produces "hello" 9 times rather than just once as you might expect. *Reasoning:* Subtle bugs, performance. == Closures == Use them liberally, especially when designing public interfaces. *Reasoning:* Closures are the best mechanism available to enforce API contracts within javascript Beware of memory leaks. Avoid referencing dom elements in short-lived closures. Instead of this: {{{ var obj = document.getElementById("foo"); obj.onclick = function(){}; }}} Use this: {{{ document.getElementById("foo").onclick = function(){}; }}} *Reasoning:* Internet explorer 6 does a poor job of resolving dom references in closures when doing garbage collection, so this will almost always yield a memory leak. == Naming == Package names all in lower case. *Reasoning:* Consistency, readability. Constructors and "Enums" with leading caps (ClassName, EnumName) *Reasoning:* Consistency, readability. Local, closure, and public variable names camel cased, with leading lower case (variableName, variable) *Reasoning:* Consistency, readability. "private" members that are publicly visible: Use a trailing underscore {{{ (foo.prototype.privateFunction_ = function()) }}} *Reasoning:* Consistency, Readability, clearly specifies API contract. ==for loops== Avoid tests in the second conditional. Acceptable styles are as follows: {{{ for (var i = 0, j = obj.length; i < j; ++i) for (var i = 0, data; data = obj[i]; ++i) for (var i = obj.length - 1; i >=0; --i) }}} Unacceptable: {{{ for (var i = 0; i < obj.length; i++) }}} *Reasoning:* Performance ==Prototype== Don't break the existing prototype if you can avoid it. Generally, augment your objects as follows: {{{ MyObject.prototype = { }; or MyObject.prototype.someFunction = function() { }; }}} == Semicolons == Always required in assignment (including return statements). For example: {{{ return foo; return function(){}; myObj.prototype.foo = function(){}; }}} *Reasoning:* Compiler / minifier compatibility, subtle bugs. ==Property access== Prefer dot notation when possible. *Reasoning:* Clarity, code size. ==Comments== We follow JSDoc commenting guidelines, which in turn inherit from Javadoc. Adhere to the [http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html Java Style guide] for your javascript code. *Reasoning:* Consistency, Readability. Variable number of arguments Functions that take a variable number of arguments should specify that this is the case by declaring a final, unused argument named var_args. *Reasoning:* Consistency, Readability. ==Optional arguments== {{{ Prefix with opt_. }}} *Reasoning:* Consistency, Readability. Never use global scope Always declare variables with var. *Reasoning:* global pollution, subtle bugs. Never use wrapper objects. This includes String, Object, Array, Boolean, and Number *Reasoning:* Performance, Consistency, Subtle bugs (see array comments) ==Eval== Never use it. For JSON, use gadgets.json.parse *Reasoning:* security vulnerabilities, performance, bugs. Long strings. Always concatenate using arrays. {{{ var myLongString = ["Hello, ", userId, ". How are you?"].join(""); instead of var myLongString = "Hello, " + userId + ". How are you?"; }}} *Reasoning:* Performance. Note: Certain future JS compilation tools might eliminate this requirement, but for now stick with it. Never use slash notation for continuations. This means you should not do this: {{{ var myString = "Hello, this is a long string \ isn't it cool?"; }}} *Reasoning:* Minification will break this. Alternative: Use array concatenation, or violate the 80-column rule if the string is only a little over the limit.