-
Notifications
You must be signed in to change notification settings - Fork 20
Open
Labels
Description
判断一个对象是不是数组类型
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]'
); //falseArray.isArray
Array.isArray 也可以弥补 typeof 的不足
Array.isArray(obj1); //false
Array.isArray(obj2); //true
Array.isArray(obj3); //false