一、typeof 不能判断变量是否为数组
var arr = [1 ,2, 3, 4];
console.log(typeof arr); // Object
二、通过 instanceof 来识别
instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
var arr = [1, 2, 3, 4];
console.log(arr instanceof Array); // true
[] instanceof Array // true
{} instanceof Array // false
var ojb = {a:1};
obj instanceof Object // true
({}) instanceof Object // true
{} instanceof Object // 报错
为什么 {} instanceof Object 会报语法错误呢?
这是因为 instanceof 前的操作数需要一个对象,而 {} 既可以识别为空的代码块,也可以识别为空对象,js 无法判断它是代码块还是空对象,但是 js 语句优先,优先识别为代码块就报错了。
三、JQuery 使用者
var arr = [1, 2];
var bool = $.isArray(arr); 判断是否为数组 返回Boolean
console.log(bool); //true
var obj = {a:1};
var bool = $.isPlainObject(obj); 判断是否为对象 返回Boolean
console.log(bool); //true
四、原型链方法判断
var ary = [1, 2, 3, 4];
console.log(ary.__proto__.constructor==Array); // true
console.log(ary.constructor==Array); //true 这两段代码是一样的
{}.constructor; // object
[].constructor; // Array
五、Object.prototype.toString.call 方法
call() 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数。fun.call(thisArg, arg1, arg2, ...)
Object.prototype.toString.call([]); // ["object Array"]
Object.prototype.toString.call({}); // ["object Object"]
六、通过 ES6 中的 Array.isArray 来识别
Array.isArray([1, 2, 3]); // true
Array.isArray({foo: 123}); // false
Array.isArray('foobar'); // false
Array.isArray(undefined); // false
instanceof VS isArray
当检测 Array 实例时,Array.isArray 优于 instanceof,因为 Array.isArray 能检测 iframes。
Polyfill
假如不存在 Array.isArray(),则在其他代码之前运行下面的代码将创建该方法。
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
拓展:不同场景下的类型检测
var class2type = {}; // Object
var getProto = Object.getPrototypeOf;
var toString = class2type.toString; // Object.prototype.toString
var hasOwn = class2type.hasOwnProperty; // Object.prototype.hasOwnProperty
var fnToString = hasOwn.toString; // Function.prototype.toString
// ObjectFunctionString = 'function Object() { [native code] }'
var ObjectFunctionString = fnToString.call(Object); // Object.toString()
var typeArr = ['Boolean', 'Number', 'String', 'Function', 'Array', 'Date','RegExp', 'Object', 'Error', 'Symbol', 'BigInt', 'Map', 'Set']; // ...
typeArr.forEach(function (name) {
class2type["[object " + name + "]"] = name.toLowerCase();
})
function toType(obj) {
if (obj == null) {
return obj + "";
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[toString.call(obj)] || "object" :
typeof obj;
}
// 使用正则
function toType(obj) {
if (obj == null) {
return obj + "";
}
if (typeof obj !== "object" || typeof obj !== "function" ) {
return typeof obj;
}
var reg = /^[object ([0-9A-Za-z]+)]$/, value = reg.exec(toString.call(obj))[1] || 'object';
return value.toLowerCase();
}
// 是否是一个函数
function isFunction(obj) {
// JS中获取object元素,在某些浏览器中,基于typeof检测这个对象,返回的是function
return typeof obj === "function" && typeof obj.nodeType !== "number" &&
typeof obj.item !== "function";
};
// 是否是window对象
function isWindow(obj) {
// undefined == null -> true
return obj != null && obj === obj.window;
};
// 检测是否为数组和类数组
function isArrayLike(obj) {
var length = !!obj && "length" in obj && obj.length,
type = toType(obj);
if (isFunction(obj) || isWindow(obj)) {
return false;
}
return type === "array" || length === 0 ||
typeof length === "number" && length > 0 && (length - 1) in obj;
}
// 检测是否为存粹对象(直属类是Object,数组这类不是)
function isPlainObject(obj) {
var proto, Ctor;
if (!obj || toType(obj) !== 'object') {
return false;
}
proto = getProto(obj);
// Objects with no prototype (e.g., `Object.create( null )`) are plain
if (!proto) {
return true;
}
// Objects with prototype are plain iff they were constructed by a global Object function
Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
}
// 检测是否是空对象
function isEmptyObject(obj) {
if (obj == null) {
return false;
}
// Object.getOwnPropertyNames 可以获取不可枚举的key Object.keys 获取可枚举的key
var keys = Object.getOwnPropertyNames(obj);
if (typeof Symbol !== 'undefined') {
keys = keys.concat(Object.getOwnPropertySymbols(obj));
}
return keys.length === 0;
}
// 是否是数字
function isNumeric(obj) {
var type = toType(obj);
return (type === "number" || type === "string") && !isNaN(obj - parseFloat(obj));
};
相关文章:js判断两个对象相等的方法