资讯专栏INFORMATION COLUMN

判断是否是数组的几种方法— (js基础复习第1期)

supernavy / 3356人阅读

摘要:如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。

1. 首先,typeof肯定是不行的

对于一些基本类型,typeof是可以判断出数据类型,但是判断一些引用类型时候,不能具体到具体哪一种类型
再来复习一下typeof的用法:

</>复制代码

  1. // 基本类型
  2. typeof 123; //number
  3. typeof "123"; //string
  4. typeof true; //boolean
  5. typeof undefined; //undefined
  6. typeof null; //object
  7. let s = Symbol;
  8. typeof s; //symbol
  9. // 引用类型
  10. typeof [1,2,3]; //object
  11. typeof {}; //object
  12. typeof function(){}; //function
  13. typeof Array; //function Array类型的构造函数
  14. typeof Object; //function Object类型的构造函数
  15. typeof Symbol; //function Symbol类型的构造函数
  16. typeof Number; //function Number类型的构造函数
  17. typeof String; //function String类型的构造函数
  18. typeof Boolean; //function Boolean类型的构造函数
2. 两种简单,但是不是十分准确的方法

</>复制代码

  1. var obj = [4,67,23];
  2. obj instanceof Array; //return true
  3. obj.constructor == Array; // return true

为什么不准确?

2.1 首先来复习一下instanceof用法

判断一个实例是否属于某种类型

</>复制代码

  1. function Foo(name) {
  2. this.name = name;
  3. }
  4. var f = new Foo("zhangsan");
  5. console.log(f instanceof Foo); //true
  6. console.log(f instanceof Object); //true

判断一个实例是否属于它的父类型

</>复制代码

  1. function Person() {};
  2. function Student() {};
  3. var p = new Person();
  4. Student.prototype = p;
  5. var s = new Student();
  6. console.log(s instanceof Student); //true
  7. console.log(s instanceof Person); //true
  8. 记忆:
  9. A instanceof C 等价于 A 是否是 C子类,或者后代?
2.2 instanceof 判断逻辑?

判断逻辑翻译成js代码如下:

</>复制代码

  1. _instanceof(f, Foo);
  2. function _instanceof(L, R) {
  3. var R = o.prototype;
  4. var L = L.__proto__;
  5. while( true) {
  6. if(L == null) {
  7. return false;
  8. }
  9. if(L == R) {
  10. return true;
  11. }
  12. L = L.__proto__;
  13. }
  14. }
2.3 instanceof 不准确的原因?

代码如下:

</>复制代码

  1. var iframe = document.createElement("iframe");
  2. document.body.appendChild(iframe);
  3. var arr = [1,2,3];
  4. xArray = window.frames[0].Array; //iframe中的构造函数
  5. var arrx = new xArray(4,5,6);
  6. console.log(arrx instanceof Array); //false
  7. console.log(arrx.constructor == Array);// false
  8. console.log(Array.prototype == xArray.prototype); //false
  9. console.log(arr instanceof xArray); //false
  10. console.log(arrx.constructor === Array);// false
  11. console.log(arr.constructor === Array);// true
  12. console.log(arrx.constructor === xArray);// true
  13. console.log(Array.isArray(arrx)); //true

解释:红宝书,p88

instanceof操作符的问题在于,它假定只有一个全局环境。如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。
如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数。

2.4 constructor 不准确的原因?

因为constructor可以被重写,所以不能确保一定是数组
example:

</>复制代码

  1. var str = "abc";
  2. str.constructor = Array;
  3. str.constructor === Array // return true

而很明显str不是数组。
而且constructor和instanceof存在同样问题,不同执行环境下,constructor判断不正确问题。

3. isArray()

最终确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的,这个方法的用法如下。

</>复制代码

  1. if(Array.isArray(value)){
  2. return true;
  3. }
4. Object.prototype.toString

如果在尚未实现isArray方法的浏览器中准确监测数组,我们需要用到Object.prototype.toString方法来判断,每一个继承自Object的对象都拥有toString的方法。

</>复制代码

  1. if(!Array.isArray){
  2. Array.isArray = function(arg){
  3. return Object.prototype.toString.call(arg)==="[object Array]"
  4. }
  5. }

自己可以封装一个获取变量类型的函数

</>复制代码

  1. function getType(obj) {
  2. return Object.prototype.toString.call(obj).slice(8,-1);
  3. }
  4. var a = [1,2,3];
  5. console.log(getType(a)); //Array
  6. var b = function(){};
  7. console.log(getType(b)); //Function
5. 参考文章

JavaScript instanceof 运算符深入剖析
javascript 判断变量是否是数组(Array)

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

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

相关文章

  • 数组的使用总结— (js基础复习2)

    摘要:前一个值,当前值,索引,数组对象产生新数组的迭代器方法类似,对数组的每个元素使用某个函数,并返回新数组和相似,传入一个返回值为布尔类型的函数。 1. 前言 数组真的是每天用了,但是有很多方法都是记不住,总是要百度查,很烦,所以才写了个数组使用总结,有什么不对的希望大家指出来。 2. 思路 先看看这些问题都记得很清楚么? 创建数组,怎么创建数组的 数组的构造方法Array有哪些方法?E...

    zhigoo 评论0 收藏0
  • 前端培训-初级阶段(13、18)

    摘要:年月欧洲计算机制造商协会发表了标准,它是的一个扩延,它也被称为年月首版年月日截止发布日期,的官方名称是,国际意在更频繁地发布包含小规模增量更新的新版本,下一版本将于年发布,命名为。 前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的...

    YorkChen 评论0 收藏0
  • 复习笔记(新手向) - JS对象声明几种方式

    摘要:二用操作符构造对象属性名属性值属性名属性值属性名属性值属性名属性值方法名方法名首先用创建一个空对象,然后用多条语句给对象添加属性方法。他的写法与三用函数声明的方式构造对象比较像,但是稍有不同。 -- 新手向知识,就不用ES6写法了。 一、字面量声明 var obj = { 属性名1 : 属性值, 属性名2 : 属性值, 属性名3 : 属性...

    davidac 评论0 收藏0
  • 【面试系列】番外:关于糯米面试

    摘要:番外关于糯米面试结果总而言之一句话糯米的面试挂了过程把面试过程中面试官的问题分享一下有几种数据类型。将一个字符串转化为数字,将数字转化为字符串。获取当前网址并从中截取信息。究其愿意还是对字符串和数组的操作不熟练,我决定深刻反思。 番外:关于糯米面试 结果 总而言之一句话:糯米的面试挂了 过程 把面试过程中面试官的问题分享一下: js有几种数据类型。 将一个字符串转化为数字,将数字转化...

    PiscesYE 评论0 收藏0

发表评论

0条评论

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