数组检测

检测constructor

v.constructor === Array

缺点:

let arr = []
console.log(arr.constructor === Array); // true 在子类中定义constructor属性,屏蔽原型上的constructor导致检测出错
arr.constructor = Object
console.log(arr.constructor === Array); // false 改写原型上的constructor,导致检测出错
Array.prototype.constructor = {}
console.log(arr.constructor === Array); // false

检测原型

v instanceof Array

缺点:

覆盖整个数组原型,然而规范对其属性描述为{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false},就是不能覆盖的意思
let arr = []
console.log(arr.constructor === Array); // true
Array.prototype = {}
console.log(arr instanceof Array); // true 跨iframe的数组,原型不共享,导致instanceof检测失效
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3)
arr instanceof Array; // false

Object.prototype.toString输出[[Class]]的默认行为

Object.prototype.toString.call(v)

缺点:

可能存在使用Symbol.toStringTag重写toString行为,导致检测失效,这里的重写是指将[object class] 中的class重写为指定值,其默认值为\[[Class]]
let arr = []
console.log(Object.prototype.toString.call(arr) === "[object Array]");
Array.prototype[Symbol.toStringTag] = "11" // [object 11]
console.log(Object.prototype.toString.call(arr) === "[object Array]");

ES6

优点:解决了以上iframe原型共享检测失效问题以及重写[[Class]]属性导致检测失效行为

Array.isArray(v)
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3)
arr instanceof Array; // false
Array.isArray(arr) // true let arr = []
console.log(Object.prototype.toString.call(arr) === "[object Array]"); // true
Array.prototype[Symbol.toStringTag] = "11" // [object 11]
console.log(Object.prototype.toString.call(arr) === "[object Array]"); // false Array.isArray(arr) // true

Array.isArray规范细节

小结

从以ducktype检测对象的数字索引、constructor、instanceof、toString方法来看,它们都在一定程度上是不可信任的,也就是会可能被人篡改导致检测异常,而isArray检测的是内部的[[Class]]属性,十分稳定,所以可以信任

最新文章

  1. ros学习笔记 - 深度传感器转换成激光数据(hector_slam)
  2. 30秒搭建Github Page
  3. iframe更新与隐藏
  4. spring mvc实现修改+删除
  5. C++ 函数后加const
  6. sao/jsp
  7. Oracle 介绍 (未完待续)
  8. CakePHP的文章分类的功能实现
  9. Ext.grid.GridPanel的属性
  10. Android程序的目录结构
  11. PHP: 异常exception
  12. git push origin master 报错 remote rejected] master -> master (branch is currently checked out)
  13. 自学Zabbix3.6.2-触发器triggers severity严重程度
  14. python爬虫如何爬知乎的话题?
  15. tomcat在Eclipse中和idea中的使用
  16. scala函数和方法的差别
  17. Android App的签名
  18. 在返回值拒绝——reference
  19. mysql中的blob和text区别
  20. java并发编程实战:第十一章----性能和可伸缩性

热门文章

  1. 物联网架构成长之路(45)-容器管理平台Rancher
  2. Worker Services的新项目模板
  3. 如何创建一个简单 APT 仓库
  4. 一个简单的利用 WebClient 异步下载的示例(一)
  5. Django学习笔记(15)——中间件
  6. 通过Filebeat把日志传入到Elasticsearch
  7. elasticsearch 入门篇
  8. ConstraintLayout 用法
  9. java web spring异步方法
  10. Centos7 安装 zabbix 4.0