返回值。例如,你用 XMLHttpRequest 发出一个 RPC 请求,服务器端相应返回 JavaScript 代码: var userOnline = false; var user = 'nusrat'; var xmlhttp = new XMLHttpRequest(); xmlhttp.open('GET', 'http://chat.google.com/isUserOnline?user=' + user, false); xmlhttp.send(''); // Server returns: // userOnline = true; if (xmlhttp.status == 200) { eval(xmlhttp.responseText); } // userOnline is now true. with() {} 原文▽别用。 使用 with 语句会让你的代码行如踏云,毫无安全感。因为用 with 添加过来的对象可能会对当 前局部作用域的属性与方法产生冲突,进而影响到整个环境。比如,下面的代码发生了什么: with (foo) { var x = 3; return x; } 回答: 啥事都可能发生。这个局部变量 x 可能会被 foo 对象里的属性所覆盖,它甚至可能会有 setter,导致在赋值 3 时会执行许多其他的代码,所以太危险了,别用 with 。 this 原文▽ 仅在构造函数,方法,闭包中去使用它。
print(arr[i]); } } 关联数组 原文▽ 永远不要用 Array 去做 map/hash/associative 要做的事情。 不允许使用关联 Arrays ……更具体的说是不允许使用非数字索引的数组(Array 不都是用数字 索引的么, 也没办法用吧除非是两个数组同索引) 。 如果你需要一个 map/hash 那就用 Object 来 代替 Array 吧, 实际上你想用的就是 Object 而不是 Array。 Array 只是继承自 Object (和 Date, RegExp 和 String 一样)。 多行字符串字面量 原文▽不要! 不要这样写: var myString = 'A rather long string of English text, an error message \ actually that just keeps going and going -- an error \ message to make the Energizer bunny blush (right through \ those Schwarzenegger shades)! Where was I? Oh yes, \ you\'ve got an error and all the extraneous whitespace is \ just gravy. Have a nice day.'; 空白字符开头字符行不能被很安全的编译剥离,以至于斜杠后面的空格可能会产生奇怪的错误。 虽然大多数脚本引擎都支持这个,但它并不是 ECMAScript 标准的一部分。 可以用+号运算符来连接每一行: var myString = 'A rather long string of English text, an error message ' + 'actually that just keeps going and going -- an error ' + 'message to make the Energizer bunny blush (right through ' + 'those Schwarzenegger shades)! Where was I? Oh yes, ' + 'you\'ve got an error and all the extraneous whitespace is ' + 'just gravy. Have a nice day.'; Array 和 Object 字面量 原文▽推荐使用。
构造函数会因为传参不当而导致理解错误。 // 长度是 3. var a1 = new Array(x1, x2, x3); // 长度是 2. var a2 = new Array(x1, x2); // 如果 x1 是自然数那数组的长度就变成了 x1 // 如果 x1 是数字但不是自然数就会报错 // 不然数组就会有一个元素 x1 var a3 = new Array(x1); // 长度是 0. var a4 = new Array(); 如上,如果传入了一个参数而不是两个,那这数组可能就不是预期的长度了。 为了避免这种情况,用更可读的数组字面量吧。 var a = [x1, x2, x3]; var a2 = [x1, x2]; var a3 = [x1]; var a4 = []; Object 构造函数没有如上问题,但考虑到可读性和一致性,用字面量更好些。 var o = new Object(); var o2 = new Object(); o2.a = 0; o2.b = 1; o2.c = 2; o2['strange key'] = 3; 应该写成: var o = {}; var o2 = { a: 0, b: 1,
{ a: 0, b: 1, lengthyName: 2 }; 只有屌丝才这样做: WRONG_Object.prototype = { a : 0, b : 1,0 lengthyName: 2 }; 函数参数 尽可能的将所有的函数参数都写在同一行上,但为了保持增强可读性,如果一行超过了 80 字符 的话可适当的换行,甚至可以每个参数都独立一行,记得格式上的优化,比如缩进 4 个空格和 对齐括号。 以下是几种常见的: // Four-space, wrap at 80. Works with very long function names, survives // renaming without reindenting, low on space. goog.foo.bar.doThingThatIsVeryDifficultToExplain = function( veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { // ... }; // Four-space, one argument per line. Works with long function names, // survives renaming, and emphasizes each argument. goog.foo.bar.doThingThatIsVeryDifficultToExplain = function( veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { // ...
(译者表示表格里的单词太多,要犯懒,想了解详细信息的可以查阅 JS2) JavaScript 类型语言 这个 JS2 提议为 JavaScript 类型定制了一种语言。当我们在 JsDoc 中注释函数参数和返回值类 型的时候会用到它。 虽然 JS2 提议在不断的进化,但编译器还是会继续支持老的类型语法,只是不建议使用而已。 Operator Name Syntax Description Deprecated Syntaxes Type Name {boolean}, {Wi ndow}, {goog.u i.Menu} Simply the name of a type. Type Application {Array.<string >} An array of strings. {Object.<strin g, number>} An object in which the keys are strings and the values are numbers. Patameterizes a type, by applying a set of type arguments to that type. The idea is analogous to generics in Java. Type Union {(number|boole an)} A number or a boolean. Indicates that a value might have type A OR type B. {(number,boolean)},{num ber|boolean},{(number|| boolean)} Record Type {{myNum: number, myObject}} An anonymous type with the given type members. Indicates that the value has the specified members with the specified types. In this case, myNum
that the braces are part of the type syntax. For example, to denote an Array of objects that have a lengthpro perty, you might write Array .<{length} >. Nullable type {?number} A number or NULL. Indicates that a value is type A or null. By default, all object types are nullable. NOTE: Function types are not nullable. {number?} Non-nullable type {!Object} An Object, but never the null value. Indicates that a value is type A and not null. By default, all value types (boolean, number, string, and undefined) are not nullable. {Object!}
arguments (a string and a boolean), and has an unknown return value. Specifies a function. Function Return Type {function(): number} A function that takes no arguments and returns a number. Specifies a function return type. Function this Type {function(this :goog.ui.Menu, string)} A function that takes one argument (a string), and executes in the context of a goog.ui.Menu. Specifies the context type of a function type. Function new Type {function(new: goog.ui.Menu, string)} A constructor that takes one argument (a string), and creates a new instance of goog.ui.Menu when called with the 'new' keyword. Specifies the constructed type of a constructor. Variable arguments {function(stri ng, ...[number ]): number} A function that takes one argument (a string), and then a variable number of Specifies variable arguments to a function.
@param {...number} var_args A variable number of arguments to an annotated function. Specifies that the annotated function accepts a variable number of arguments. Function optio nal arguments {function(?str ing=, number=)} A function that takes one optional, nullable string and one optional number as arguments. The = syntax is only for function ty pe declarations. Specifies optional arguments to a function. Function optio nal arguments (in @param annot ations) @param {number=} opt_argument An optional parameter of type number. Specifies that the annotated function accepts an optional argument. The ALL type {*} Indicates that the variable can take on any type. The UNKNOWN type {?} Indicates that the variable can take on any type, and the compiler should not type-check
* @private */ this.myValue_ = opt_value; } 以上代码是告诉编译器说 myValue_ 有可能是一个对象,null,还可能是 undefined。 注意:可选参数 opt_value 被声明为 {Object=},而并不是 {Object|undefined}。这是 因为可选属性可能是定义的或未定义的,虽然说明确写 undefined 也没关系,但读起来前边的更 爽。 最后,注意可空和可选都是正交属性,下面的四个声明都是不同的: /** * Takes four arguments, two of which are nullable, and two of which are * optional. * @param {!Object} nonNull Mandatory (must not be undefined), must not be null. * @param {Object} mayBeNull Mandatory (must not be undefined), may be null. * @param {!Object=} opt_nonNull Optional (may be undefined), but if present, * must not be null! * @param {Object=} opt_mayBeNull Optional (may be undefined), may be null. */ function strangeButTrue(nonNull, mayBeNull, opt_nonNull, opt_mayBeNull) { // ... }; 类型定义 类型定义也可以复杂化,一个函数可以接受元素节点的内容: /** * @param {string} tagName * @param {(string|Element|Text|Array.<Element>|Array.<Text>)} contents * @return {!Element} */ goog.createElement = function(tagName, contents) { ... }; 你可以定义 @typedef 标记的常用类型表达式,例如:
* @param {goog.ElementContent} contents * @return {!Element} */ goog.createElement = function(tagName, contents) { ... }; 模板属性 编译器已经有限的支持模板类型。它只能推断的类型,这在一个匿名函数字面量从类型的这个论 点,是否这个论点是缺失的。 The compiler has limited support for template types. It can only infer the type of this inside an anonymous function literal from the type of the this argument and whether the this argument is missing. /** * @param {function(this:T, ...)} fn * @param {T} thisObj * @param {...*} var_args * @template T */ goog.bind = function(fn, thisObj, var_args) { ... }; // Possibly generates a missing property warning. goog.bind(function() { this.someProperty; }, new SomeClass()); // Generates an undefined this warning. goog.bind(function() { this.someProperty; }); 注释 原文▽ 使用 JSDoc 我们鼓励依照 C++ style for comments 的风格。 所有的文件,类,方法和属性都应该以 JSDoc 风格来进行注释。 行内注释使用 // 。
/** * A JSDoc comment should begin with a slash and 2 asterisks. * Inline tags should be enclosed in braces like {@code this}. * @desc Block tags should always start on their own line. */ JSDoc 缩进 如果你不得不换行块标签,那就应该缩进四个空格以保持注释内容的结构清晰。 /** * Illustrates line wrapping for long param/return descriptions. * @param {string} foo This is a param with a description too long to fit in * one line. * @return {number} This returns something that has a description too long to * fit in one line. */ project.MyClass.prototype.method = function(foo) { return 5; }; 你不应该缩进 @fileoverview 命令。 尽管缩进至与上排注释同列并不怎么好,但也是可以接受的。 /** * This is NOT the preferred indentation method. * @param {string} foo This is a param with a description too long to fit in * one line. * @return {number} This returns something that has a description too long to * fit in one line. */ project.MyClass.prototype.method = function(foo) { return 5; }; JSDoc 的 HTML
<tt>, <strong>, <ul>, <ol>, <li>, <a>等等。 昂所以纯文本状态并不会被格式化,比如换行和空格什么的都会被忽略掉: /** * Computes weight based on three factors: * items sent * items received * last timestamp */ 上面的结果其实是: Computes weight based on three factors: items sent items received items received 所以,可以用这种方式: /** * Computes weight based on three factors: * <ul> * <li>items sent * <li>items received * <li>last timestamp * </ul> */ 关于写注释更多信息可以去看一下 JavaDoc 风格指南。 顶部或文件头的注释 顶部注释是为了让读者能够很快的明了这个文件里的代码是干嘛的,描述应包括作者,年代,依 赖关系或兼容信息等相关,下面的例子: // Copyright 2009 Google Inc. All Rights Reserved. /** * @fileoverview Description of file, its uses and information * about its dependencies. * @author [email protected] (Firstname Lastname) */ 类的注释 对于类的注释,肯定要写功能和类型的描述,还有一些参数和原型描述等信息。
{string} arg1 An argument that makes this more interesting. * @param {Array.<number>} arg2 List of numbers to be processed. * @constructor * @extends {goog.Disposable} */ project.MyClass = function(arg1, arg2) { // ... }; goog.inherits(project.MyClass, goog.Disposable); 方法和函数的注释 应该有参数和返回值的描述,方法描述要以使用者的身份去写。 /** * Operates on an instance of MyClass and returns something. * @param {project.MyClass} obj Instance of MyClass which leads to a long * comment that needs to be wrapped to two lines. * @return {boolean} Whether something occured. */ function PR_someMethod(obj) { // ... } 一些简单的 get 方法没有参数和其他影响的,可以忽略描述。 属性的描述 /** * Maximum number of things per pane. * @type {number} */ project.MyClass.prototype.someProperty = 4; JSDoc 标签参考 (译者注:看到解释有一大段,译者犯懒,有想看的请查阅 JSDoc Toolkit Tag Reference ) Tag Template & Examples Description @author @author [email protected] Document the author of a file or the owner of a test, generally only used
textareas. * @author [email protected] (Uthur Pendragon) */ in the @fileoverview comment. @code {@code ...} For example: /** * Moves to the next position in the selection. * Throws {@code goog.iter.StopIteration} when it * passes the end of the range. * @return {Node} The node at the next position. */ goog.dom.RangeIterator.proto type.next = function() { // ... }; Indicates that a term in a JSDoc description is code so it may be correctly formatted in generated documentation. @const @const For example: /** @const */ var MY_BEER = 'stout'; /** * My namespace's favorite kind of beer. * @const * @type {string} */ mynamespace.MY_BEER = 'stout'; Marks a variable as read-only and suitable for inlining. Generates warnings if it is rewritten. Constants should also be ALL_CAPS, but the annotation should help eliminate reliance on the naming convention. Although @final is listed at jsdoc.org and is supported as equivalent to @const in the compiler, it is discouraged. @const is consistent with JS1.5's const keyword. Note that changes to properties of const objects are not currently prohibited by the compiler (inconsistent with C++ const
can be omitted if it can be clearly inferred. If present, it must be on its own line. An additional comment about the variable is optional. @constructo r @constructor For example: /** * A rectangle. * @constructor */ function GM_Rect() { ... } Used in a class's documentation to indicate the constructor. @define @define {Type} description For example: /** @define {boolean} */ var TR_FLAGS_ENABLE_DEBUG = true; /** @define {boolean} */ goog.userAgent.ASSUME_IE = false; Indicates a constant that can be overridden by the compiler at compile-time. In the example, the compiler flag --define='goog.userAgent. ASSUME_IE=true' could be specified in the BUILD file to indicate that the constant goog.userAgent.ASSUME_ IE should be replaced with true. @deprecated @deprecated Description For example: /** * Determines whether a node is a field. * @return {boolean} True if the contents of * the element are editable, but the element * itself is not. * @deprecated Use isField(). */ BN_EditUtil.isTopEditableFie Used to tell that a function, method or property should not be used any more. Always provide instructions on what callers should use instead.
For example: /** * Enum for tri-state values. * @enum {number} */ project.TriState = { TRUE: 1, FALSE: -1, MAYBE: 0 }; @export @export For example: /** @export */ foo.MyPublicClass.prototype. myPublicMethod = function() { // ... }; Given the code on the left, when the compiler is run with the --generate_exports flag, it will generate the code: goog.exportSymbol('foo.MyPublicClas s.prototype.myPublicMethod', foo.MyPublicClass.prototype.myPubli cMethod); which will export the symbols to uncompiled code. Code that uses the@export annotation must either 1. include //javascript/clos ure/base.js, or 2. define both goog.exportSymbol an d goog.exportProperty wi th the same method signature in their own codebase. @extends @extends Type @extends {Type} Used with @constructor to indicate that a class inherits from another class. Curly braces around the type
* @extends goog.ds.BasicNodeList */ goog.ds.EmptyNodeList = function() { ... }; are optional. @externs @externs For example: /** * @fileoverview This is an externs file. * @externs */ var document; Declares an externs file. @fileovervi ew @fileoverview Description For example: /** * @fileoverview Utilities for doing things that require this very long * but not indented comment. * @author [email protected] (Uthur Pendragon) */ Makes the comment block provide file level information. @implements @implements Type @implements {Type} For example: Used with @constructor to indicate that a class implements an interface. Curly braces around the type are optional.
Shape.prototype.draw = function() {}; /** * @constructor * @implements {Shape} */ function Square() {}; Square.prototype.draw = function() { ... }; @inheritDoc @inheritDoc For example: /** @inheritDoc */ project.SubClass.prototype.t oString() { // ... }; Deprecated. Use @override instead. Indicates that a method or property of a subclass intentionally hides a method or property of the superclass, and has exactly the same documentation. Notice that @inheritDoc implies @override. @interface @interface For example: /** * A shape. * @interface */ function Shape() {}; Shape.prototype.draw = function() {}; /** * A polygon. * @interface * @extends {Shape} */ Used to indicate that the function defines an inteface.
@lends {objectName} For example: goog.object.extend( Button.prototype, /** @lends {Button.prototype} */ { isButton: function() { return true; } }); Indicates that the keys of an object literal should be treated as properties of some other object. This annotation should only appear on object literals. Notice that the name in braces is not a type name like in other annotations. It's an object name. It names the object on which the properties are "lent". For example, @type {Foo} means "an instance of Foo", but @lends {Foo} means "the constructor Foo". The JSDoc Toolkit docs have more information on this annotation. @license or @preserve @license Description For example: /** * @preserve Copyright 2009 SomeThirdParty. * Here is the full license text and copyright * notice for this file. Note that the notice can span several * lines and is only terminated by the closing star and slash: */ Anything marked by @license or @preserve will be retained by the compiler and output at the top of the compiled code for that file. This annotation allows important notices (such as legal licenses or copyright text) to survive compilation unchanged. Line breaks are preserved. @noalias @noalias For example: /** @noalias */ function Range() {} Used in an externs file to indicate to the compiler that the variable or function should not be aliased as part of the alias externals pass of the compiler. @nosideeffe cts @nosideeffects This annotation can be used as part of function and constructor declarations to indicate that calls to the declared
}; /** @nosideeffects */ var noSideEffectsFn2 = function() { // ... }; /** @nosideeffects */ a.prototype.noSideEffectsFn3 = function() { // ... }; function have no side-effects. This annotation allows the compiler to remove calls to these functions if the return value is not used. @override @override For example: /** * @return {string} Human-readable representation of project.SubClass. * @override */ project.SubClass.prototype.t oString() { // ... }; Indicates that a method or property of a subclass intentionally hides a method or property of the superclass. If no other documentation is included, the method or property also inherits documentation from its superclass. @param @param {Type} varname Description For example: /** * Queries a Baz for items. * @param {number} groupNum Subgroup id to query. * @param Used with method, function and constructor calls to document the arguments of a function. Type names must be enclosed in curly braces. If the type is omitted, the compiler will not type-check the parameter.
search everything. */ goog.Baz.prototype.query = function(groupNum, term) { // ... }; @private @private For example: /** * Handlers that are listening to this logger. * @type Array.<Function> * @private */ this.handlers_ = []; Used in conjunction with a trailing underscore on the method or property name to indicate that the member is private. Trailing underscores may eventually be deprecated as tools are updated to enforce @private. @protected @protected For example: /** * Sets the component's root element to the given element. Considered * protected and final. * @param {Element} element Root element for the component. * @protected */ goog.ui.Component.prototype. setElementInternal = function(element) { // ... }; Used to indicate that the member or property is protected. Should be used in conjunction with names with no trailing underscore. @return @return {Type} Description Used with method and function calls to document the return type. When writing descriptions for boolean parameters,
the last item. */ goog.Baz.prototype.getLastId = function() { // ... return id; }; prefer "Whether the component is visible" to "True if the component is visible, false otherwise". If there is no return value, do not use an @return tag. Type names must be enclosed in curly braces. If the type is omitted, the compiler will not type-check the return value. @see @see Link For example: /** * Adds a single item, recklessly. * @see #addSafely * @see goog.Collect * @see goog.RecklessAdder#add ... Reference a lookup to another class function or method. @supported @supported Description For example: /** * @fileoverview Event Manager * Provides an abstracted interface to the * browsers' event systems. * @supported So far tested in IE6 and FF1.5 */ Used in a fileoverview to indicate what browsers are supported by the file. @suppress @suppress {warning1|warning2} For example: /** Suppresses warnings from tools. Warning categories are separated by |.
@template For example: /** * @param {function(this:T, ...)} fn * @param {T} thisObj * @param {...*} var_args * @template T */ goog.bind = function(fn, thisObj, var_args) { ... }; This annotation can be used to declare a template typename. @this @this Type @this {Type} For example: pinto.chat.RosterWidget.exte rn('getRosterElement', /** * Returns the roster widget element. * @this pinto.chat.RosterWidget * @return {Element} */ function() { return this.getWrappedComponent_(). getElement(); }); The type of the object in whose context a particular method is called. Required when the this keyword is referenced from a function that is not a prototype method. @type @type Type @type {Type} Identifies the type of a variable, property, or expression. Curly braces are not required around most types,
{string} */ var hexId = hexId; but some projects mandate them for all types, for consistency. @typedef @typedef For example: /** @typedef {(string|number)} */ goog.NumberLike; /** @param {goog.NumberLike} x A number or a string. */ goog.readNumber = function(x) { ... } This annotation can be used to declare an alias of a more complex type. 推荐使用的有: @typedef @type @this @template @suppress @supported @see @return @protected @private @param @override @nosideeffects @noalias @lends @interface @inheritDoc @implements @fileoverview @externs @extends @export @enum @deprecated @define @constructor @const @code 你可能在第三方代码中看到其他的 JSDoc 标注。昂它们在 Google 代码中并不怎么鼓励使用, 但谁知道呢可能未来的某一天就突然的用起来了呢,先看看吧: @augments @argument @borrows @class @constant @constructs @default @event @example @field @function