JavaScript 类型
强烈建议你去使用编译器.
如果使用 JSDoc, 那么尽量具体地, 准确地根据它的规则来书写类型说明. 目前支持两种JS2和 JS1.x 类型规范.
JavaScript 类型语言
JS2 提议中包含了一种描述 JavaScript 类型的规范语法, 这里我们在 JSDoc 中采用其来描述函数参数和返回值的类型.
JSDoc 的类型语言, 按照 JS2 规范, 也进行了适当改变, 但编译器仍然支持旧语法.
名称 | 语法 | 描述 | 弃用语法 |
---|---|---|---|
普通类型 | {boolean} , {Window} , {goog.ui.Menu} |
普通类型的描述方法. | |
复杂类型 | {Array.<string>} 字符串数组. {Object.<string, number>} 键为字符串, 值为整数的对象类型. |
参数化类型, 即指定了该类型中包含的一系列”类型参数”. 类似于 Java 中的泛型. | |
联合类型 | {(number|boolean)} 一个整数或者布尔值. |
表示其值可能是 A 类型, 也可能是 B 类型 | {(number,boolean)} , {number|boolean} , {(number||boolean)} |
记录类型 | {{myNum: number, myObject}} 由现有类型组成的类型. |
表示包含指定成员及类型的值. 这个例子中, myNum 为 number 类型, myObject 为任意类型. 注意大括号为类型语法的一部分. 比如, Array.<{length}> , 表示一具有 length 属性的 Array 对象. |
|
可为空类型 | {?number} 一个整型数或者为 NULL |
表示一个值可能是 A 类型或者 null .默认, 每个对象都是可为空的. 注意: 函数类型不可为空. |
{number?} |
非空类型 | {!Object} 一个对象, 但绝不会是 null 值. |
说明一个值是类型 A 且肯定不是 null.默认情况下, 所有值类型 (boolean, number, string, 和 undefined) 不可为空. | {Object!} |
函数类型 | {function(string, boolean)} 具有两个参数 ( string 和 boolean) 的函数类型, 返回值未知. |
说明一个函数. | |
函数返回类型 | {function(): number} 函数返回一个整数. |
说明函数的返回类型. | |
函数的 this 类型 |
{function(this:goog.ui.Menu, string)} 函数只带一个参数 (string), 并且在上下文 goog.ui.Menu 中执行. |
说明函数类型的上下文类型. | |
可变参数 | {function(string, ...[number]): number} 带一个参数 (字符类型) 的函数类型, 并且函数的参数个数可变, 但参数类型必须为 number. |
说明函数的可变长参数. | |
可变长的参数 (使用 @param 标记) |
@param {...number} var_args 函数参数个数可变. |
使用标记, 说明函数具有不定长参数. | |
函数的 缺省参数 | {function(?string=, number=)} 函数带一个可空且可选的字符串型参数, 一个可选整型参数. = 语法只针对 function 类型有效. |
说明函数的可选参数. | |
函数 可选参数 (使用 @param 标记) |
@param {number=} opt_argument number 类型的可选参数. |
使用标记, 说明函数具有可选参数. | |
所有类型 | {*} |
表示变量可以是任何类型. |
JavaScript中的类型
number
1
1.0
-5
1e5
Math.PI
Number
new Number(true)
string
字符串值
'Hello'
"World"
String(42)
String
new String('Hello')
new String(42)
boolean
布尔值
true
false
Boolean(0)
Boolean
new Boolean(true)
RegExp
new RegExp('hello')
/world/g
Date
new Date
new Date()
null
null
undefined
undefined
void
没有返回值
function f() {
return;
}
Array
类型不明确的数组
['foo', 0.3, null]
[]
Array.<number>
[11, 22, 33]
Array.<Array.<string>>
Array.<Array.<string>>
Object
{}
{foo: 'abc', bar: 123, baz: null}
Object.<string>
{'foo': 'bar'}
Object.<number, string>
键为整数, 值为字符串的对象.
注意, JavaScript 中, 键总是被转换成字符串, 所以
obj['1'] == obj[1]
.
也所以, 键在 for…in 循环中是字符串类型. 但在编译器中会明确根据键的类型来查找对象.
var obj = {};
obj[1] = 'bar';
Function
function(x, y) {
return x * y;
}
function(number, number): number
函数值
function(x, y) {
return x * y;
}
SomeClass
/** @constructor */
function SomeClass() {}
new SomeClass();
SomeInterface
/** @interface */
function SomeInterface() {}
SomeInterface.prototype.draw = function() {};
project.MyClass
/** @constructor */
project.MyClass = function () {}
new project.MyClass()
project.MyEnum
枚举
/** @enum {string} */
project.MyEnum = {
BLUE: '#0000dd',
RED: '#dd0000'
};
Element
DOM 中的元素
document.createElement('div')
Node
DOM 中的节点.
document.body.firstChild
HTMLInputElement
DOM 中, 特定类型的元素.
htmlDocument.getElementsByTagName('input')[0]
可空 vs. 可选 参数和属性
JavaScript 是一种弱类型语言, 明白可选, 非空和未定义参数或属性之间的细微差别还是很重要的.
对象类型(引用类型)默认非空. 注意: 函数类型默认不能为空.
除了字符串, 整型, 布尔, undefined 和 null 外, 对象可以是任何类型.
/**
* Some class, initialized with a value.
* @param {Object} value Some value.
* @constructor
*/
function MyClass(value) {
/**
* Some value.
* @type {Object}
* @private
*/
this.myValue_ = value;
}
告诉编译器 myValue_
属性为一对象或 null. 如果 myValue_
永远都不会为 null, 就应该如下声明:
/**
* Some class, initialized with a non-null value.
* @param {!Object} value Some value.
* @constructor
*/
function MyClass(value) {
/**
* Some value.
* @type {!Object}
* @private
*/
this.myValue_ = value;
}
这样, 当编译器在代码中碰到 MyClass
为 null 时, 就会给出警告.
函数的可选参数可能在运行时没有定义, 所以如果他们又被赋给类属性, 需要声明成:
/**
* Some class, initialized with an optional value.
* @param {Object=} opt_value Some value (optional).
* @constructor
*/
function MyClass(opt_value) {
/**
* Some value.
* @type {Object|undefined}
* @private
*/
this.myValue_ = opt_value;
}
这告诉编译器 myValue_
可能是一个对象, 或 null, 或 undefined.
注意: 可选参数 opt_value
被声明成 {Object=}
, 而不是 {Object|undefined}
. 这是因为可选参数可能是 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) {
// ...
};