您的位置:首页 > Web前端 > JavaScript

《编写可维护的 JavaScript》读书笔记第8章:避免“空比较”

2013-12-24 00:14 351 查看
想判断一个变量(或参数)是不是一个数组,显然不应该只是这样写:
if (items != null) { // 不好的写法
items.sort();
...
}

1. 检测原始值

5种原始值:字符串、数字、布尔值、null 和 undefined。最佳选择是使用 typeof 运算符判断其类型:
typeof 字符串 === "string"

typeof 数字 === "number"

typeof 布尔值 === "number"

typeof undefined === "undefined"

2. 检测引用值

除了原始值之外的值都是引用(也称作对象)。内置引用类型:Object、Array、Date 和 Error。
使用 instanceof 运算符检测引用值的类型:vaue instanceof constructor。
示例:
// 检测日期
if (value instanceof Date) {
console.log(value.getFullYear());
}

// 检测正则表达式
if (value instanceof RegExp) {
if (value.test(anotherValue)){
console.log("Matches");
}
}

// 检测 Error
if (value instanceof Error) {
throw value;
}
instanceof 不仅检测构造对象的构造器,还检测原型链。
var now = new Date();

console.log(now instanceof Object); // true
console.log(now instanceof Date); // true
instanceof 是检测自定义类型的唯一方法,但是有一个严重的限制:不能跨帧(frame)。
假设一个浏览器帧(frame A)里的一个对象被传入到另一个帧(frame B)中,两个帧里都定义了构造函数 Person,如果来自帧A的对象是帧A的Person的实例,那么:
// true
frameAPersonInstance instanceof frameAPerson

// false
frameAPersonInstance instanceof frameBPerson
这个限制对内置类型――函数和数组也一样生效。对于这两个类型来说,一般用不着使用 instanceof。
2.1 检测函数JavaScript 中的函数是引用类型,同样存在 Function 构造函数,每个函数都是它的实例。
function myFunc() {}

// 不好的写法
console.log(myFunc instanceof Function); // true
应该使用 typeof,会返回“function”:
function myFunc() {}

// 好的写法
console.log(typeof myFunc === "function"); // true
在 IE 8 和更早版本的 IE 浏览器中,使用 typeof 检测 DOM 节点中的函数都返回“object”而不是“function”。
可以使用 in 运算符来检测 DOM 的方法:
// 检测 DOM 方法
if ("querySelectorAll" in document) {
images = document.querySelectorAll("img");
}
2.2 检测数组使用 Douglas Crockford 推荐的“鸭式辨型”(duck typing)检测:
// 采用鸭式辨型的方法检测数组
function isArray(value) {
return typeof value.sort === "function";
}
这种检测方法假定数组是唯一拥有 sort() 方法的对象。如果传入的参数是一个包含 sort() 方法的对象,也会返回 true。
Juriy Zaytsev 给出了一种优雅的解决方案:
function isArray(value) {
return Object.prototype.toString.call(value) === "[object Array]";
}
该方法被大多数 JavaScript 类库采纳。
对自定义对象不要用这种方法,比如内置 JSON 对象使用这种方法将返回“[object JSON]”。
ECMAScript5 将 Array.isArray() 正式引入 JavaScript,因此很多 JavaScript 类库都类似地实现了这个方法:
function isArray(value) {
if (typeof Array.isArray === "function") {
return Array.isArray(value);
} else {
return Object.prototype.toString.call(value) === "[object Array]";
}
}

3. 检测属性

// 不好的写法:检测假值
if (object[propertyName]) {
// 一些代码
}

// 不好的写法:和 null 比较
if (object[propertyName] != null) {
// 一些代码
}

// 不好的写法:和 undefined 比较
if (object[propertyName] != undefined) {
// 一些代码
}
最好方法是使用 in 运算符。
var object = {
count: 0,
related: null
};

// 好的写法
if ("count" in object) {
// 这里的代码会执行
}

// 不好的写法:检测假值
if (object["count"]) {
// 这里的代码不会执行
}

// 好的写法
if ("related" in object) {
// 这里的代码会执行
}

// 不好的写法:检测是否为 null
if (object["related"] != null) {
// 这里的代码不会执行
}
使用 hasOwnProperty() 方法检测属性是否存在,但在 IE 8 及更早版本中,DOM 对象并非继承自 Object,因此它们没有这个方法。
// 对于所有非 DOM 对象来说,这是好的写法
if (object.hasOwnProperty("related")) {
// 执行这里的代码
}

// 如果不确定是否为 DOM 对象,则这样写
if ("hasOwnProperty" in object && object.hasOwnProperty("related")) {
// 执行这里的代码
}
本文出自 “神奇的未来” 博客,请务必保留此出处http://qczhang.blog.51cto.com/6094768/1344235
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐