本文共 4161 字,大约阅读时间需要 13 分钟。
本节书摘来自异步社区《编写可维护的JavaScript》一书中的第1章,第1.7节,作者:【美】Nicholas C. Zakas著,更多章节内容可以访问云栖社区“异步社区”公众号查看
JavaScript中包含一些类型的原始值:字符串、数字、布尔值、null和undefined。同样也包含对象直接量和数组直接量。这其中,只有布尔值是自解释(self-explanatory)的,其他的类型或多或少都需要思考一下它们如何才能更精确地表示出来。
1.7.1 字符串
在JavaScript中,字符串是独一无二的。字符串可以用双引号括起来,也可以用单引号括起来。比如:// 合法的JavaScript代码var name = "Nicholas says, \"Hi.\"";// 也是合法的JavaScript代码var name = 'Nicholas says, "Hi"';
和Java、PHP这些语言不同,使用单引号括起字符串和双引号括起字符串在功能上并无不同。除了内部出现字符串界定符(string delimiter)时需要转义之外,两种做法在功效上完全一致。因此在这段示例代码中,在使用双引号括起来的字符串里需要对双引号进行转义,而在使用单引号括起来的字符串里则不必如此。你需要关心的是,你的代码应当从头到尾只保持一种风格。
Crockford的编程规范和jQuery核心风格指南都使用双引号来括住字符串。Google的JavaScript风格指南使用单引号括住字符串。我倾向于使用双引号,因为我经常在Java和JavaScript之间来回切换。由于Java只使用双引号括住字符串,我发现如果在JavaScript中也使用这个约定,我会很容易在上下文之间相互切换。这类问题应当在制定规范之初就考虑清楚:这样可以最大程度地减轻工程师的开发负担。
关于字符串还有另外一个问题需要注意,即创建多行字符串。这个特性并非来自JavaScript语言本身,却在几乎所有的(JavaScript)引擎中正常工作。
// 不好的写法var longString = "Here's the story, of a man \named Brady.";
尽管从技术上讲这种写法是非法的JavaScript语法,但的确能在代码中创建多行字符串。通常不推荐使用这种写法,因为它是一种奇技淫巧而非语言特性,并且在Google的JavaScript风格指南中是明确禁止的。多行字符串的一种替代写法是,使用字符串连接符(+)将字符串分成多份。
// Goodvar longString = "Here's the story, of a man " + "named Brady.";
1.7.2 数字
在JavaScript中的数字类型只有一种,因为所有数字形式—整数和浮点数—都存储为相同的数据类型。还有一些其他的数字直接量格式来表示不同的数据格式。其中大部分写法都很好用,但也有一些写法有问题。// 整数var count = 10;// 小数var price = 10.0;var price = 10.00;// 不推荐的小数写法:没有小数部分var price = 10.;// 不推荐的小数写法:没有整数部分var price = .1;// 不推荐的写法:八进制写法已经被弃用了var num = 010;// 十六进制写法var num = 0xA2;// 科学计数法var num = 1e23;
前两种有问题的写法分别是省略了小数部分,比如10.,和省略了整数部分,比如.1。每种写法都有同一个问题:很难搞清楚被省略小数点之前或之后的部分是不小心丢掉了还是刻意为之。很可能是开发者不小心漏掉了。因此为了避免歧义,请不要省略小数点之前或之后的数字。Dojo编程风格指南明确禁止这两种写法。JSLint和JSHint对这两种写法都会给出警告。
最后一个有问题的写法是八进制数字写法。长久以来,JavaScript支持八进制数字写法是很多错误和歧义的根源。数字直接量010不是表示10,而是表示八进制中的8。大多数开发者对八进制格式并不熟悉,也很少用到,所以最好的做法是在代码中禁止八进制直接量。尽管在所有流行的编程规范中没有关于此的规定,但在JSlint和JSHint中都会对八进制直接量给出警告。
1.7.3 null
null是一个特殊值,但我们常常误解它,将它和undefined搞混。在下列场景中应当使用null。用来初始化一个变量,这个变量可能赋值为一个对象。
用来和一个已经初始化的变量比较,这个变量可以是也可以不是一个对象。当函数的参数期望是对象时,用作参数传入。当函数的返回值期望是对象时,用作返回值传出。还有下面一些场景不应当使用null。不要使用null来检测是否传入了某个参数。
不要用null来检测一个未初始化的变量。这里有一些示例代码。// 好的用法var person = null;// 好的用法function getPerson() { if (condition) { return new Person("Nicholas"); } else { return null; }}// 好的用法var person = getPerson();if (person !== null) { doSomething();}// 不好的写法:用来和未初始化的变量比较var person;if (person != null) { doSomething();}// 不好的写法:检测是否传入了参数function doSomething(arg1, arg2, arg3, arg4) { if (arg4 != null) { doSomethingElse(); }}
理解null最好的方式是将它当做对象的占位符(placeholder)。这个规则在所有的主流编程规范中都没有提及,但对于全局可维护性来说至关重要。
关于null的陷阱会在第8章有更进一步的讨论。
1.7.4 undefined
undefined是一个特殊值,我们常常将它和null搞混。其中一个让人颇感困惑之处在于null == undefined结果是true。然而,这两个值的用途却各不相同。那些没有被初始化的变量都有一个初始值,即undefined,表示这个变量等待被赋值。比如:// 不好的写法var person;console.log(person === undefined); //true
尽管这段代码能正常工作,但我建议避免在代码中使用undefined。这个值常常和返回“undefined”的typeof运算符混淆。事实上,typeof的行为也很让人费解,因为不管是值是undefined的变量还是未声明的变量,typeof运算结果都是“undefined”。比如:
//foo未被声明var person;console.log(typeof person); //"undefined"console.log(typeof foo); //"undefined"
在这段代码中,person和foo都会导致typeof返回“undefined”,哪怕person和foo在其他场景中的行为有天壤之别(在语句中使用foo会报错,而使用person则不会报错)。
通过禁止使用特殊值undefined,可以有效地确保只在一种情况下typeof才会返回“undefined”:当变量未声明时。如果你使用了一个可能(或可能不会)赋值为一个对象的变量时,则将其赋值为null。
// 好的做法var person = null;console.log(person === null); //true
将变量初始值赋值为 null 表明了这个变量的意图,它最终很可能赋值为对象。typeof运算符运算null的类型时返回“object”,这样就可以和undefined区分开了。
1.7.5 对象直接量
创建对象最流行的一种做法是使用对象直接量,在直接量中直接写出所有属性,这种方式可以取代先显式地创建Object的实例然后添加属性的这种做法。比如,我们很少见到下面这种写法。// 不好的写法var book = new Object();book.title = "Maintainable JavaScript";book.author = "Nicholas C. Zakas";
对象直接量允许你将所有的属性都括在一对花括号内。直接量可以高效地完成非直接量写法相同的任务,非直接量写法语法看起来更复杂。
当定义对象直接量时,常常在第一行包含左花括号,每一个属性的名值对都独占一行,并保持一个缩进,最后右花括号也独占一行。比如:
// 好的写法var book = { title: "Maintainable JavaScript", author: "Nicholas C. Zakas"};
这种写法在开源JavaScript代码中能经常看到。尽管没有归纳入文档中,Google的JavaScript风格指南非常推荐使用这种写法。Crockford的编程规范也推荐使用直接量代替Object构造函数,但并没有给出具体的书写格式。
1.7.6 数组直接量
和对象直接量类似,数组直接量是JavaScript中定义数组最简洁的一种方式。不赞成显式地使用Array构造函数来创建数组,比如:// 不好的写法var colors = new Array("red", "green", "blue");var numbers = new Array(1, 2, 3, 4);可以使用两个方括号将数组初始元素括起来,来替代使用Array构造函数的方式来创建数组。
转载地址:http://fnpfx.baihongyu.com/