使用 typeof bar === "object" 来确定 bar 是否是对象的潜在陷阱是什么?如何避免这个陷阱?
潜在陷阱是:当 bar 为 null 时,也会被认为是对象。
如何避免:方法如下
1、我们发现当bar为null时,typeof bar === "object"的结果也是true,可见这种单一判断不再可取。
/*null*/
var bar = null;
console.log(typeof bar === "object");//true
console.log((bar !== null) && (typeof bar === "object"));//fasle
当我们加上 "bar !== null" 这一限制条件后,得到了想要的结果。可还有几种其他情况也需要注意。
2、判断函数
/*函数*/
var bar1 = function(){
// do something
}
console.log(typeof bar1 === "object");//fasle
console.log((bar1 !== null) && (typeof bar1 === "object"));//fasle
console.log((bar1 !== null) && ((typeof bar1 === "object")||(typeof bar1 === "function")));//true
3、判断数组
/*数组*/
var bar2 = [];
console.log(typeof bar2 === "object");//true
console.log((bar2 !== null) && (typeof bar2 === "object"));//true
console.log((bar2 !== null) && (typeof bar2 === "object") && (toString.call(bar2) !== "[object Array]"));//fasle
4、另附Object.prototype.toString.call()方法的使用,以便和 "typeof"方法做对比区分。
/* ps:toString.call()方法 */
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call("abc")); // "[object String]"
console.log(Object.prototype.toString.call(123)); // "[object Number]"
console.log(Object.prototype.toString.call(true)); // "[object Boolean]"
/* 函数类型 */
function fn(){
console.log("test");
}
console.log(Object.prototype.toString.call(fn)); // "[object Function]"
/* 日期类型 */
var date = new Date();
console.log(Object.prototype.toString.call(date)); // "[object Date]"
/* 数组类型 */
var arr = [1,2,3];
console.log(Object.prototype.toString.call(arr)); // "[object Array]"
基础最重要,好多陷阱都是在大家不太注意的小点上。我本着从头开始,狠抓细节的学习态度,想要从一点一滴里去注意有可能是日后潜在的大bug。
以上。
2018 08 03 补充内容:关于变量连续声明中的变量类型判断
(function(){
var a = b = 3;
})();
console.log(typeof a == 'undefined'); // true
console.log(typeof b == 'undefined'); // fasle
如上所示,在匿名函数中,连续声明变量b和a,然后控制台输出其变量类型的判断结果,发现a确实是局部变量,所以是 undefined,结果为true;但b却不是,说明b是全局变量。
notes:
var a = b = 3 不等同于 var b = 3; var a = b;
而是等同于 b = 3; var a = b;
所以此时的变量b声明是不加关键字var的,也就是说变量b是全局变量。
ps: 如果使用严格模式 "use strict";,则控制台不会有输出,直接报错 "b is not defined"。
网友评论