现代 JavaScript 开发编程风格Idiomatic.js指南中文版(2)

无论你选择单引号还是双引号都无所谓,在 JavaScript 中它们在解析上没有区别。而绝对需要强制的是一致性。 永远不要在同一个项目中混用两种引号,选择一种,并保持一致。

F. 行末和空行

留白会破坏区别并使用变更不可读。考虑包括一个预提交的 hook 自动删除行末和空行中的空格。

三、类型检测 (来源于 jQuery Core Style Guidelines)

A. 直接类型(实际类型,Actual Types)

String:

复制代码 代码如下:


typeof variable === "string"


Number:

复制代码 代码如下:


typeof variable === "number"


Boolean:

复制代码 代码如下:


typeof variable === "boolean"


Object:

复制代码 代码如下:


typeof variable === "object"


Array:

复制代码 代码如下:


Array.isArray( arrayLikeObject )
(如果可能的话)


Node:

复制代码 代码如下:


elem.nodeType === 1


null:

复制代码 代码如下:


variable === null


null or undefined:

复制代码 代码如下:


variable == null


undefined:

全局变量:

复制代码 代码如下:


typeof variable === "undefined"


局部变量:

复制代码 代码如下:


variable === undefined


属性:

复制代码 代码如下:


object.prop === undefined
object.hasOwnProperty( prop )
"prop" in object


B. 转换类型(强制类型,Coerced Types)

考虑下面这个的含义...

给定的 HTML:

复制代码 代码如下:


<input type="text" value="1">

// 3.B.1.1

// `foo` 已经被赋予值 `0`,类型为 `number`
var foo = 0;

// typeof foo;
// "number"
...

// 在后续的代码中,你需要更新 `foo`,赋予在 input 元素中得到的新值

foo = document.getElementById("foo-input").value;

// 如果你现在测试 `typeof foo`, 结果将是 `string`
// 这意味着你在 if 语句检测 `foo` 有类似于此的逻辑:

if ( foo === 1 ) {

importantTask();

}

// `importantTask()` 将永远不会被执行,即使 `foo` 有一个值 "1"

// 3.B.1.2

// 你可以巧妙地使用 + / - 一元运算符强制转换类型以解决问题:

foo = +document.getElementById("foo-input").value;
//    ^ + 一元运算符将它右边的运算对象转换为 `number`

// typeof foo;
// "number"

if ( foo === 1 ) {

importantTask();

}

// `importantTask()` 将被调用


对于强制类型转换这里有几个例子:

复制代码 代码如下:


// 3.B.2.1

var number = 1,
  string = "1",
  bool = false;

number;
// 1

number + "";
// "1"

string;
// "1"

+string;
// 1

+string++;
// 1

string;
// 2

bool;
// false

+bool;
// 0

bool + "";
// "false"
// 3.B.2.2

var number = 1,
  string = "1",
  bool = true;

string === number;
// false

string === number + "";
// true

+string === number;
// true

bool === number;
// false

+bool === number;
// true

bool === string;
// false

bool === !!string;
// true
// 3.B.2.3

var array = [ "a", "b", "c" ];

!!~array.indexOf("a");
// true

!!~array.indexOf("b");
// true

!!~array.indexOf("c");
// true

!!~array.indexOf("d");
// false

// 值得注意的是上述都是 "不必要的聪明"
// 采用明确的方案来比较返回的值
// 如 indexOf:

if ( array.indexOf( "a" ) >= 0 ) {
  // ...
}
// 3.B.2.3

var num = 2.5;

parseInt( num, 10 );

// 等价于...

~~num;

num >> 0;

num >>> 0;

// 结果都是 2

// 时刻牢记心底, 负值将被区别对待...

var neg = -2.5;

parseInt( neg, 10 );

// 等价于...

~~neg;

neg >> 0;

// 结果都是 -2
// 但是...

neg >>> 0;

// 结果即是 4294967294

四、对比运算

复制代码 代码如下:


// 4.1.1
// 当只是判断一个 array 是否有长度,相对于使用这个:
if ( array.length > 0 ) ...

// ...判断真伪, 请使用这种:
if ( array.length ) ...

// 4.1.2
// 当只是判断一个 array 是否为空,相对于使用这个:
if ( array.length === 0 ) ...

// ...判断真伪, 请使用这种:
if ( !array.length ) ...

// 4.1.3
// 当只是判断一个 string 是否为空,相对于使用这个:
if ( string !== "" ) ...

// ...判断真伪, 请使用这种:
if ( string ) ...

// 4.1.4
// 当只是判断一个 string 是为空,相对于使用这个:
if ( string === "" ) ...

// ...判断真伪, 请使用这种:
if ( !string ) ...

// 4.1.5
// 当只是判断一个引用是为真,相对于使用这个:
if ( foo === true ) ...

// ...判断只需像你所想,享受内置功能的好处:
if ( foo ) ...

// 4.1.6
// 当只是判断一个引用是为假,相对于使用这个:
if ( foo === false ) ...

// ...使用叹号将其转换为真
if ( !foo ) ...

// ...需要注意的是:这个将会匹配 0, "", null, undefined, NaN
// 如果你 _必须_ 是布尔类型的 false,请这样用:
if ( foo === false ) ...

// 4.1.7
// 如果想计算一个引用可能是 null 或者 undefined,但并不是 false, "" 或者 0,
// 相对于使用这个:
if ( foo === null || foo === undefined ) ...

// ...享受 == 类型强制转换的好处,像这样:
if ( foo == null ) ...

// 谨记,使用 == 将会令 `null` 匹配 `null` 和 `undefined`
// 但不是 `false`,"" 或者 0
null == undefined

总是判断最好、最精确的值,上述是指南而非教条。

复制代码 代码如下:


// 4.2.1
// 类型转换和对比运算说明

// 首次 `===`,`==` 次之 (除非需要松散类型的对比)

// `===` 总不做类型转换,这意味着:

"1" === 1;
// false

// `==` 会转换类型,这意味着:

"1" == 1;
// true

// 4.2.2
// 布尔, 真 & 伪

// 布尔:
true, false

// 真:
"foo", 1

// 伪:
"", 0, null, undefined, NaN, void 0

五、实用风格

复制代码 代码如下:


// 5.1.1
// 一个实用的模块

(function( global ) {
  var Module = (function() {

var data = "secret";

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgpfwy.html