判断一个对象是不是数组类型
typeof
少部分人可能首先会想到 typeof
var n = 3,
b = true,
s = 'Hello',
x = null,
y,
obj1 = function() {},
obj2 = {},
obj3 = [],
obj4 = new Date();
console.log(
typeof n, //number
typeof b, //boolean
typeof s, //string
typeof x, //object
typeof y, //undefined
typeof obj1, //function
typeof obj2, //object
typeof obj3, //object
typeof obj4 //object
);
可以看出 typeof
是可以判断出基本数据类型的,函数也能判断出来,但是对象、数组、日期都会返回 object,这样就根本无法判断一个对象是不是数组类型。所以 typeof
宣告无能为力
判断其父级原型对象
var obj1 = {},
obj2 = [1, 2, 3],
obj3 = new Date();
console.log(obj1.__proto__ == Array.prototype); //false
console.log(obj2.__proto__ == Array.prototype); //true
console.log(obj3.__proto__ == Array.prototype); //false
但是 __proto__
是内部属性,本不应该被访问到,我们可以用 Object.getPrototypeOf(obj)
方法来代替他,虽然这个方法其实内部原理也是他,但是还是有不同的。
console.log(Object.getPrototypeOf(obj1) == Array.prototype); //false
console.log(Object.getPrototypeOf(obj2) == Array.prototype); //true
console.log(Object.getPrototypeOf(obj3) == Array.prototype); //false
判断其构造函数
obj instanceof Array
判断 obj
是不是被构造函数 Array
创造出来的
console.log(obj1 instanceof Array); //false
console.log(obj2 instanceof Array); //true
console.log(obj3 instanceof Array); //false
但instanceof
不仅判断直接父类型,而是所有在原型链上的类型,都返回 true
,所以如果你创建一个对象但是把他的 __proto__
指向 Array
的原型,然后判断其类型,也会返回 true
。
obj1.__proto__ = Array.prototype;
console.log(obj1 instanceof Array); //true
判断对象内部的 class 属性
每个对象内部,都有一个隐藏的 class
属性,记录该对象创建时的数据类型 class
属性不会随继承关系的改变而改变。(就相当于查人的 DNA 了吧,小样还想伪装。)
这里有一个问题:内置类型的原型对象中几乎都重写了新的 toString()
,只有最顶层的 toString()
才能输出对象的 class
属性值,
因此我们可以用 call
来使用最牛皮的身份鉴别
console.log(
Object.prototype.toString.call(obj1) == /*[object Object]*/ '[object Array]'
); //false
console.log(
Object.prototype.toString.call(obj2) == /*[object Array]*/ '[object Array]'
); //true
console.log(
Object.prototype.toString.call(obj3) == /*[object Date]*/ '[object Array]'
); //false
Array.isArray
Array.isArray
也可以弥补 typeof
的不足
Array.isArray(obj1); //false
Array.isArray(obj2); //true
Array.isArray(obj3); //false
更多文章来自我的 github ,求个 star 鼓励一下吧!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。