bfchengnuo / MyRecord

平时充电做的笔记,一个程序猿的自我修养.
https://bfchengnuo.com/MyRecord/
33 stars 8 forks source link

JavaScript中检测对象的方法? #52

Closed bfchengnuo closed 4 years ago

bfchengnuo commented 6 years ago

起因: 在用 instanceof 操作符来判断 JS 中某个对象是否是数组时,明明是却返回 false,于是发现了一个坑。。。 于是,来总结一下。


typeof操作符

这种方法对于一些常用的类型来说那算是毫无压力,比如 Function、String、Number、Undefined 等,但是要是检测Array的对象就不起作用了。 用法:

alert(typeof null); // "object"  
alert(typeof function  () {
    return 1;
}); // "function"  
alert(typeof '梦龙小站'); // "string"  
alert(typeof 1); // "number"  
alert(typeof a); // "undefined" 
alert(typeof undefined); // "undefined"  
alert(typeof []);     // "object" 

这个用的一般很少,比较鸡肋。

instanceof操作符

这个操作符和 JavaScript 中面向对象有点关系。 因为这个操作符是检测对象的原型链是否指向构造函数的 prototype 对象的。 用法:alert([] instanceof Array); // true 这个是我用的最多的一个了。

对象的constructor属性

除了 instanceof,每个对象还有 constructor 的属性,利用它似乎也能进行 Array 的判断。 示例:alert([].constructor === Array); // true


注意事项

上面第 2 种和第 3 种方法貌似无懈可击,但是实际上还是有些漏洞的; 当你在多个 frame 中来回穿梭的时候,这两种方法就不太好用了。 由于每个 iframe 都有一套自己的执行环境,跨 frame 实例化的对象彼此是不共享原型链的,因此导致上述检测代码失效!


修复办法

来看一看真正的“无懈可击”的办法:

ECMAScript5 将 Array.isArray() 正式引 入JavaScript,目的就是准确地检测一个值是否为数组(IE8- 不支持)。 感兴趣的可以看看 Object.prototype.toString 的行为,但对于自定义对象请不要使用这种方法,总之,他们都能解决上面的问题。

示例写法:

var arr = [1,2,3,1];  
var arr2 = [{ abac : 1, abc : 2 }];  

function isArrayFn(value){
  if (typeof Array.isArray === "function") {
    return Array.isArray(value);    
  }else{
    return Object.prototype.toString.call(value) === "[object Array]";    
  }
}
alert(isArrayFn(arr));// true 
alert(isArrayFn(arr2));// true 
bfchengnuo commented 6 years ago

引用:https://blog.csdn.net/lee_magnum/article/details/11555981