资讯专栏INFORMATION COLUMN

判断一个对象是不是数组,有几种办法?

Cruise_Chan / 3034人阅读

摘要:这是一个出现过无数次的话题,这里再次重写仅作为个人的学习笔记,谢谢观看。

这是一个出现过无数次的话题,这里再次重写仅作为个人的学习笔记,谢谢观看。

0、typeof

typeof 运算符的主要作用就是用来检测数据的类型,一般情况下我们都是使用它来判断数据类型,但是这里,我把typeof 放在0的位置,因为 typeof 不能检测到数组类型!typeof 所能识别的类型只有原始类型(Undefined,Null,Boolean,Number,String,Symbol )以及 function 和 object。

需要注意的是null,null所检测出来的结果是"object",因为在js中,null除了作为空引用的存在,它也是对象整个原型链上最顶端的存在,即

Object.prototype.__proto__ === null;//true

其他使用typeof的场景:

// Numbers
typeof 3.14 === "number";
typeof Math.LN2 === "number"; 
typeof Infinity === "number"; 
typeof NaN === "number"; //尽管NaN是"Not-A-Number"的缩写

// Strings
typeof "bla" === "string"; 
typeof (typeof 1) === "string"; //typeof总是返回一个字符串

// Booleans
typeof true === "boolean";

// Symbols
typeof Symbol() === "symbol";
typeof Symbol.iterator === "symbol";

// Undefined
typeof undefined === "undefined";

// null
typeof null === "object";//从一开始出现JavaScript就是这样的

// function
typeof function(){} === "function";
typeof class C{} === "function"

// Objects
typeof {a:1} === "object";

// 下面的结果是什么?
typeof new Boolean(true) === "object";
typeof new Number(1) === "object";
typeof new String("abc") === "object";
//new 所创建的都是对象,赋值给变量是执行了内部valueOf()或者toString()函数

最后,typeof不能检测到数组类型!

1、验证原型对象:

从原型链上寻找(认祖归宗)

1、Object.getPrototypeOf(obj) == Array.prototype

getPrototypeOf: 这是Object自带的一个API,作用是获取一个对象的原型对象

2、var bool = Array.prototype.isPrototypeOf(obj)

每个对象都有一个isPrototypeOf的API,继承自Object.prototype,用来 判断father(Array)是否是child(obj)的父对象

2、验证构造函数:

从构造函数上判断(它的亲娘)

1、obj.constructor == Array

构造函数的prototype指向原型对象,同时,原型对象有constructor指回构造函数对象,constructor只在原型对象上有

2、var bool = obj instanceof Array

instance: 判断对象(obj)是否由构造函数(Array)创建出来

这种方法有一个问题,就是验证不够严格。 即使对象创建时不是使用数组创建的,但是只要原型链上有数组类型,也认为是数组,如下面一段代码:

function Test(){}
Test.prototype = Array.prototype;
let test = new Test();
test instanceof Array;//true
3、检查内部属性class + call或apply:

这个class不是es6中对象声明的class

这个class是每个对象中记录对象创建时使用的类型的属性,一旦对象被创建,class属性就无法被修改!

获得class的唯一的办法就是调用Object.prototype中的toString()方法

输出结果有"[object Object]","[object Function]"等

问题: 几乎所有内置对象的原型对象都重写了Object中的toString方法,所有内置对象的子对象,都无法直接调到Object的toString。

let arr = [1];
arr.toString();//"1"
let date = new Date();
date.toString();//"Wed Mar 07 2018 16:22:16 GMT+0800 (中国标准时间)"

虽然直接使用不行,但是我们可以利用js的call和apply函数来解决这个问题

Object.prototype.toString.call(obj)=="[object Array]"

使用这个方法判断其他类型:

console.log(Object.prototype.toString.call("jerry"));//[object String]
console.log(Object.prototype.toString.call(12));//[object Number]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(new Date));//[object Date]
console.log(Object.prototype.toString.call(/d/));//[object RegExp]
function Person(){};
console.log(Object.prototype.toString.call(new Person));//[object Object]
4、ES5中的API:Array.isArray(obj)

这是ES5出的一个API,专门用来判断一个对象是不是数组的,所以,看到这里有没有感觉前面都白看了....

他的用法也很简单:

var arr = [1,2,3,4];
Array.isArray(arr);//true
写在最后

如果文中有什么错误的地方,还请大家给予指出,另外大家如果还有什么别的方法的话,也可以在评论区写下或私信我,大家集思广益,相互学习,共同进步。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93237.html

相关文章

  • 2019前端面试那些事儿

    摘要:虽然今年没有换工作的打算但为了跟上时代的脚步还是忍不住整理了一份最新前端知识点知识点汇总新特性,语义化浏览器的标准模式和怪异模式和的区别使用的好处标签废弃的标签,和一些定位写法放置位置和原因什么是渐进式渲染模板语言原理盒模型,新特性,伪 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总1.HTMLHTML5新特性,语义化浏览器的标准模式和怪...

    JeOam 评论0 收藏0
  • 2019前端面试那些事儿

    摘要:虽然今年没有换工作的打算但为了跟上时代的脚步还是忍不住整理了一份最新前端知识点知识点汇总新特性,语义化浏览器的标准模式和怪异模式和的区别使用的好处标签废弃的标签,和一些定位写法放置位置和原因什么是渐进式渲染模板语言原理盒模型,新特性,伪 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总1.HTMLHTML5新特性,语义化浏览器的标准模式和怪...

    QLQ 评论0 收藏0
  • 2018 浅谈前端面试那些事

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    LiuRhoRamen 评论0 收藏0
  • 2018 浅谈前端面试那些事

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    stormgens 评论0 收藏0
  • 2018 浅谈前端面试那些事

    摘要:声明的变量不得改变值,这意味着,一旦声明变量,就必须立即初始化,不能留到以后赋值。 虽然今年没有换工作的打算 但为了跟上时代的脚步 还是忍不住整理了一份最新前端知识点 知识点汇总 1.HTML HTML5新特性,语义化浏览器的标准模式和怪异模式xhtml和html的区别使用data-的好处meta标签canvasHTML废弃的标签IE6 bug,和一些定位写法css js放置位置和原因...

    Hujiawei 评论0 收藏0

发表评论

0条评论

Cruise_Chan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<