可能出现类型检查并不能准确判断表达式的类型的情况,可以在注释里添加类型标注,并在中括号内写出表达式的类型,如果有对该类型的注解就更好了。
/* @type {number} / (x)
(/* @type {number} / x)
可空 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也没关系,但读起来前边的更爽。
最后,注意可空和可选都是正交属性,下面的四个声明都是不同的:
/**
* 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) {
// ...
};