在 JavaScript
里使用 typeof
判断数据类型,只能区分除了 null 以外的基本数据类型,即:number
、string
、undefined
、boolean
、object
对于 null
、array
、function
、object
来说,使用 typeof
都会统一返回 object
字符串。因此,要想区分对象、数组、函数、单纯使用 typeof
是不行的。
在JS中,可以通过 Object.prototype.toString
方法,判断某个对象属于哪种内置类型。
分为 null
、string
、boolean
、number
、undefined
、array
、function
、object
、date
、math
。
1、判断基本数据类型
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call("abc"); // "[object String]"
Object.prototype.toString.call(123); // "[object Number]"
Object.prototype.toString.call(true); // "[object Boolean]"
2、判断原生引用数据类型
// 函数类型
Function fn(){
console.log("test");
}
Object.prototype.toString.call(fn); // "[object Function]"
// 日期类型
var date = new Date();
Object.prototype.toString.call(date); // "[object Date]"
// 数组类型
var arr = [1,2,3];
Object.prototype.toString.call(arr); // "[object Array]"
// 正则表达式
var reg = /[hbc]at/gi;
Object.prototype.toString.call(reg); // "[object RegExp]"
// 自定义类型
function Person(name, age) {
this.name = name;
this.age = age;
}
var person = new Person("Rose", 18);
Object.prototype.toString.call(arr); // "[object Object]"
很明显这种方法不能准确判断 person
是 Person
类的实例,而只能用 instanceof
操作符来进行判断,如下所示:
console.log(person instanceof Person); // true
3、判断原生 JSON 对象
var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON);
console.log(isNativeJSON);// 输出结果为"[object JSON]"说明JSON是原生的,否则不是;
注意:Object.prototype.toString() 本身是允许被修改的,而我们目前所讨论的关于Object.prototype.toString()这个方法的应用都是假设 toString() 方法未被修改为前提的。
4、实例:为 Array 添加一个去除重复项的方法
题目:
input:
[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN].uniq()
output:
[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a']
这里要注意,NaN === NaN 为 false,{} === {}为false。
Array.prototype.uniq = function() {
if (!this.length) return this;
let res = []
let hasNaN = false
let temp = {}
this.forEach(item => {
const itemType = Object.prototype.toString.call(item)
if (itemType === '[object Object]') {
// 对象类型
res.push(item)
} else if (isNaN(item) && itemType === '[object Number]') {
// NaN
if (!hasNaN) {
hasNaN = true
res.push(item)
}
} else {
console.log('最后的', item, res)
if (!res.includes(item)) {
res.push(item)
}
}
})
return res
}
另一种解法:
Array.prototype.uniq = function () {
let res = [];
let hasNaN = false;
this.forEach(x => {
if (res.indexOf(x) === -1) {
if (x != x) {
if (!hasNaN) {
res.push(x);
hasNaN = true;
}
} else {
res.push(x);
}
}
})
return res;
}