js判断数组和对象的方法

一、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判断两个对象相等的方法


已发布

分类

来自

标签: