2

js判断数组和对象的方法

 2 years ago
source link: https://xushanxiang.com/js-judge-array-object.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一、typeof 不能判断变量是否为数组

var arr = [1 ,2, 3, 4];
console.log(typeof arr); // Object
JavaScript

二、通过 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 // 报错
JavaScript

为什么 {} 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
JavaScript

四、原型链方法判断

var ary = [1, 2, 3, 4];
console.log(ary.__proto__.constructor==Array); // true
console.log(ary.constructor==Array); //true 这两段代码是一样的

{}.constructor; // object
[].constructor; // Array
JavaScript

五、Object.prototype.toString.call 方法

call() 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数。fun.call(thisArg, arg1, arg2, ...)

Object.prototype.toString.call([]); // ["object Array"]
Object.prototype.toString.call({}); // ["object Object"]
JavaScript

六、通过 ES6 中的 Array.isArray 来识别

Array.isArray([1, 2, 3]);  // true
Array.isArray({foo: 123}); // false
Array.isArray('foobar');   // false
Array.isArray(undefined);  // false
JavaScript

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]';
  };
}
JavaScript

拓展:不同场景下的类型检测

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));
};
JavaScript

相关文章:js判断两个对象相等的方法


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK