Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

对象类型的鉴别 #10

Open
MLuminary opened this issue May 9, 2018 · 0 comments
Open

对象类型的鉴别 #10

MLuminary opened this issue May 9, 2018 · 0 comments

Comments

@MLuminary
Copy link
Owner

判断一个对象是不是数组类型

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant