怎么去区分一个变量是一个数组仍是一个对象呢?html
看到这个题目,可能首先就会typeof,typeof是最基本的数据类型判断方式,在不考虑es6的状况下,typeof可能的返回值有下面这些:es6
"undefined" //若是这个值未定义 "boolean" //若是这个值是布尔值 "string" //若是这个值是字符串 "number" //若是这个值是数值 "object" //若是这个值是对象或null "function" //若是这个值是函数
你能够发现typeof可能的返回值并无array,也就是说typeof并不能帮你检测出一个数组。事实上,不管引用的是什么类型的对象,它都返回 "object"。若是使用typeof去检测一个数组,返回的也将会是"object"。面试
instanceof运算符用来判断一个构造函数的prototype属性所指向的对象是否存在另一个要检测对象的原型链上。
使用它的方式是:obj instanceof Object
这句话检测Object.prototype是否存在于参数obj的原型链上。
其实它已经可以很好区别开对象和数组了,看下面的例子:数组
var arr = [1, 2]; var obj = { name: 'name' } console.log(arr instanceof Array); //true console.log(obj instanceof Array); //false
但它也有一丢丢问题,既然它会去在整个原型链上去找,而ECMAScript中Object是全部对象的基础,那么,若是使用instanceof去判断一个数组是否是对象的时候,会不会也返回true呢?函数
var arr = [1,2]; console.log(arr instanceof Object); //true console.log(arr instanceof Array); //true
答案是确定的,因此感受这种判断方式也有小瑕疵。prototype
constructor 属性返回对建立此对象的函数的引用。因此大多数时候它返回的都是一个对象的构造函数。
看例子:设计
var arr = [1,2]; console.log(arr.constructor === Array); //true console.log(arr.constructor === Object); //false
但既然想要挑刺,咱们就想一想这种方式有什么问题。constructor属性实际上是存在一个对象的原型中的,因此,若是他的原型被改变了,这种方法还会有用么?
仍是例子:code
var arr = [1,2]; arr.__proto__ = {} console.log(arr.constructor === Array); //false console.log(arr.constructor === Object); //true
哈哈,不错所料的,咱们改变了arr的__proto__属性为一个对象以后,constructor也给咱们作出了错误的判断,因此,这种方法也有被玩坏的可能。htm
最后就是经过toString()方法,数组原型和对象原型定义的toString()方法不一样。对象
参考:http://www.cnblogs.com/ziyunf...
接着看例子:
var arr = [1, 2]; var obj = { name: "name", } console.log(Object.prototype.toString.call(arr) === '[object Array]'); //true console.log(Object.prototype.toString.call(boj) === '[object Array]'); //false
看到这道题仍是我第一次面试的时候,比较萌新,抱的态度也是去积累点经验,准备的不充分。被问到这个题的时候,首先个人第一反应是找一个数组中有的,对象中没有的属性去判断,好比length,但说出来我就后悔了,对象中没有length这个属性难道咱们不能给它赋一个么,而那时我还知道若是用typeof的话,他俩都会返回object。想到了构造函数可能不同,但说怎么判断就有点想不出词了,就持续懵逼中...
这篇内容参考了《JavaScript高级程序设计》和一篇文章:http://www.cnblogs.com/Walker...