今天看到一篇文章非常有意思,数组怎么证明是数组,还有最近被爆出来的各种顶替高考的事件。
你怎么证明是你自己。
JavaScript有五种方法可以确定一个值到底是什么类型,分别是typeof运算符,constructor法,instanceof运算符,Object.prototype.toString方法以及Array.isArray法。
1、typeof运算符判断类型
typeof是javascript原生提供的判断数据类型的运算符,它会返回一个表示参数的数据类型的字符串,例如:
let str = 'helloworld'
console.log(typeof(str)) //String
typeof转换结果
let nu = null;
let obj = {};
let arr = [];
console.log(typeof(nu)); //Object
console.log(typeof(obj)); //Object
console.log(typeof(arr)); //Object
由此可见,typeof不能判断出数组是否为数组,数组归为了object类型。
2、用instanceof判断
instanceof运算符可以用来判断某个构造函数的prototype属性所指向的對象是否存在于另外一个要检测对象的原型链上。在使用的时候语法如下:
object instanceof constructor
就是要判断一个Object是不是数组(在JavaScript当中,数组实际上也是一种对象),如果这个Object的原型链上能够找到Array构造函数的话,那么这个Object应该及就是一个数组,如果这个Object的原型链上只能找到Object构造函数的话,那么它就不是一个数组。
const arr = [];
const obj = {};
console.log(arr instanceof Array);//true
console.log(arr instanceof Object);//true,在数组的原型链上也能找到Object构造函数
console.log(obj instanceof Array);//false
由此可见,使用instanceof运算符可以分辨数组和对象,可以判断数组是数组。
3、用constructor判断
实例化的数组拥有一个constructor属性,这个属性指向生成这个数组的方法。
const arr = [];
console.log(arr.constructor);//function Array(){ [native code] }
由此可见,数组是有一个叫Array的函数实例化的。
判断其他类型
const obj = {};
console.log(obj.constructor);//function Object(){ [native code] }
const reg = /^[0-9]$/;
console.log(reg.constructor);//function RegExp() { [native code] }
const nu = null;
console.log(nu.constructor);//报错
看来这是一个很好的方法,那么我们这样判断:
const arr = [];
console.log(arr.constructor == Array);//true
不过,constructor是可以修改的,修改了就不能做出正确的判断了:
const arr = [];
//改变了原来的constructor属性
a.contrtuctor = Object;
console.log(arr.constructor == Array);//false (no!!!!)
console.log(arr.constructor == Object);//true (god!!!)
console.log(arr instanceof Array);//true (可见这个可以)
所以,有事没事别乱改,最后搞得怀疑人生了。
4、用Object的toString方法判断
在JavaScript中,每一个继承自Object的对象都拥有toString的方法。
如果一个对象的toString方法没有被重写过的话,那么toString方法将会返回"[object type]",其中的type代表的是对象的类型,根据type的值,我们就可以判断这个疑似数组的对象到底是不是数组了。
const a = ['Hello','Howard'];
const b = {0:'Hello',1:'Howard'};
const c = 'Hello Howard';
a.toString();//"Hello,Howard"
b.toString();//"[object Object]"
c.toString();//"Hello,Howard"
由此可见,只有对象会返回[object Object],会显示它的type,其他的都是字符串,所以我们要调用,它原型上的apply或call来执行toString的上下文。
const a = ['Hello','Howard'];
const b = {0:'Hello',1:'Howard'};
const c = 'Hello Howard';
Object.prototype.toString.call(a);//"[object Array]"
Object.prototype.toString.call(b);//"[object Object]"
Object.prototype.toString.call(c);//"[object String]"
可见返回了它自己的type
apply同样适用
const a = ['Hello','Howard'];
const b = {0:'Hello',1:'Howard'};
const c = 'Hello Howard';
Object.prototype.toString.apply(a);//"[object Array]"
Object.prototype.toString.apply(b);//"[object Object]"
Object.prototype.toString.apply(c);//"[object String]"
这个toString方法也是可以修改的,
let arr = []
Object.prototype.toString = () => {
arr = '111'
}
Object.prototype.toString.call(arr) //undefined
还是,有事没事别乱改,最后搞得怀疑人生了。
5.用Array对象的isArray方法判断
可以说这方法是最nb的一个了,它只认原配,什么小三啊,顶替者它都不管,你只要是数组,就返回true,不是数组就false,就是这么霸道。
let arr1 = []
let arr2 = {}
console.log(Array.isArray(arr1)) //true
console.log(Array.isArray(arr2)) //false
重写一下toString方法
let arr1 = []
let arr2 = {}
Object.prototype.toString = () => {
arr1 = '111'
}
console.log(Array.isArray(arr1)) //true
console.log(Array.isArray(arr2)) //false
依旧是原配,再搞一下它的constructor
let arr1 = []
let arr2 = {}
Object.prototype.toString = () => {
arr1 = '111'
}
arr1.constructor = arr2.constructor
console.log(Array.isArray(arr1)) //true
console.log(Array.isArray(arr2)) //false
还是原配,这下可以随便改了,哎,真香。
Array.isArray是ES5标准中增加的方法,部分比较老的浏览器可能会有兼容问题,所以为了增强健壮性,建议还是给Array.isArray方法进行判断,增强兼容性,重新封装的方法如下:
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
文章属转载,仅学习使用,原文链接https://segmentfault.com/a/1190000006150186。
数组都有这么多方法证明自己是数组,你怎么证明你是自己,欢迎评论。