最短的IE判断var ie=!-[1,]分析


Posted in Javascript onMay 28, 2014

 以前最短的IE判定借助于IE不支持垂直制表符的特性搞出来的。

 

 var ie = !+"\v1";

 

仅仅需要7bytes!参见这篇文章,《32 bytes, ehr ... 9, ehr ... 7!!! to know if your browser is IE》,讲述外国人是如何把IE的判定从32 bytes一步步缩简成7 bytes!的故事但这纪录今年1月8日被一个俄国人打破了,现在只要6 bytes!它利用了IE与标准浏览器在处理数组的toString方法的差异做成的。对于标准游览器,如果数组里面最后一个字符为逗号,JS引擎会自动剔除它。

var ie = !-[1,];

这句代码在IE9之前曾被称为世界上最短的IE判定代码。代码虽短但确包含了不少javascript基础知识在里面。在这个例子中代码执行时会先调用数组的toString()方法 ,执行[1,].toString()在IE6,7,8中将会得到"1,"。然后表达式就变为!-"1,"。再尝试把"1,"转换成数值类型得到NaN ,再对NaN取负得到值仍为NaN。最后执行!NaN返回true。下面通过分解这个语句来回顾下代码中所涉及到的javascript知识:

1. 浏览器的数组字面量解析差异

[1,]表示使用javascript的数组字面量定义了一个数组。 在IE6,7,8中数组有两个元素,数组中的值分别为1,undefined。在标准的浏览器中会忽略第一个元素后的undefined,数组只包含一个元素1。

2. 数组的toString()方法

调用数组对象的toString()方法时会对数组中的每个元素调用toString()方法,如果元素的值为NULL或者undefined时会返回空的字符串,然后将得到的每项的值拼成一个使用 逗号","分隔的字符串。

3. 一元减号运算符

使用一元减号运算符时如果运算数是数值类型则直接对运算数取负,否则会先尝试把运算数转换为数值类型,转换过程相当于执行Number函数,然后再对得到的结果取负。

4. 逻辑非运算

执行逻辑非运算时如果操作数为NaN、NULL或undefined 时返回 true。

JavaScript可以这么写:

var ie = !-[1,];   

   alert(ie); 

如果从非IE的角度判定,可以省一个比特,因为我们做兼容时,绝大多数情况都是IE与非IE地开工。 var notIE = -[1,];

if(-[1,]){  

     alert("这不是IE浏览器!");  

}else{  

     alert("这是IE浏览器!");  

}

通过上面的知识可以得出代码 var ie = !-[1,]; 其实等价于 var ie = !(-Number([1,].toString())); 在IE6\7\8中值为true。

因为IE6/7/8都不会忽略[1,].ToString()这个bug,即得到的是"1,";而-Number([1,].toString())即为-Number("1,")得到的结果是NaN;然后!(-Number([1,].toString()))即为!(NaN)即得到true。一切的前提是IE6/7/8都有[1,].ToString()=>"1,"这个bug,而其它浏览器(应该是大部分吧~~)则是[1,].ToString()=>"1"。

最近发现有朋友这样使用用来提示用户升级浏览器

<script>
!-[1,] && alert('您使用的是 IE6-8 版本的浏览器,\n\n建议用 Chrome, Firefox, IE9+ 浏览!');
</script>
Javascript 相关文章推荐
JavaScript 原型与继承说明
Jun 09 Javascript
js操作textarea方法集合封装(兼容IE,firefox)
Feb 22 Javascript
这些年、我收集的JQuery代码小结
Aug 01 Javascript
js 自定义个性下拉选择框示例
Aug 20 Javascript
javascript中创建对象的几种方法总结
Nov 01 Javascript
JQuery中阻止事件冒泡几种方式及其区别介绍
Jan 15 Javascript
Node.js环境下JavaScript实现单链表与双链表结构
Jun 12 Javascript
Angularjs在初始化未完毕时出现闪烁问题的解决方法分析
Aug 05 Javascript
详解vue项目的构建,打包,发布全过程
Nov 23 Javascript
vue的.vue文件是怎么run起来的(vue-loader)
Dec 10 Javascript
layui使用templet格式化表格数据的方法
Sep 16 Javascript
Vue获取页面元素的相对位置的方法示例
Feb 05 Javascript
jQuery 1.9使用$.support替代$.browser的使用方法
May 27 #Javascript
什么是cookie?js手动创建和存储cookie
May 27 #Javascript
js打开windows上的可执行文件示例
May 27 #Javascript
JavaScript数值数组排序示例分享
May 27 #Javascript
JavaScript作用域链示例分享
May 27 #Javascript
Node调试工具JSHint的安装及配置教程
May 27 #Javascript
javaScript使用EL表达式的几种方式
May 27 #Javascript
You might like
PHP实现MySQL更新记录的代码
2008/06/07 PHP
fleaphp下不确定的多条件查询的巧妙解决方法
2008/09/11 PHP
PHP速成大法
2015/01/30 PHP
php中switch与ifelse的效率区别及适用情况分析
2015/02/12 PHP
JS跨域代码片段
2012/08/30 Javascript
jquery数组封装使用方法分享(jquery数组遍历)
2014/03/25 Javascript
Javascript获取当前时间函数和时间操作小结
2014/10/01 Javascript
jQuery中的pushStack实现原理和应用实例
2015/02/03 Javascript
javascript格式化json显示实例分析
2015/04/21 Javascript
jquery仅用6行代码实现滑动门效果
2015/09/07 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
2016/01/15 Javascript
浅析JavaScript中var that=this
2017/02/17 Javascript
javascript实现二叉树的代码
2017/06/08 Javascript
webpack+vue-cil中proxyTable处理跨域的方法
2018/07/20 Javascript
Vue框架TypeScript装饰器使用指南小结
2019/02/18 Javascript
在vue-cli 3中给stylus、sass样式传入共享的全局变量
2019/08/12 Javascript
Nuxt使用Vuex的方法示例
2019/09/06 Javascript
jstree中的checkbox默认选中和隐藏示例代码
2019/12/29 Javascript
[51:52]Liquid vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.24
2019/09/10 DOTA
Python HTMLParser模块解析html获取url实例
2015/04/08 Python
处理Python中的URLError异常的方法
2015/04/30 Python
深入解读Python解析XML的几种方式
2016/02/16 Python
基于python实现简单日历
2018/07/28 Python
python用win32gui遍历窗口并设置窗口位置的方法
2019/07/26 Python
详解pyinstaller selenium python3 chrome打包问题
2019/10/18 Python
python中删除某个元素的方法解析
2019/11/05 Python
Original Penguin英国官方网站:美国著名休闲时装品牌
2016/10/30 全球购物
eDreams巴西:廉价机票,酒店优惠和度假套餐
2017/04/14 全球购物
小学生开学感言
2014/02/28 职场文书
推荐信格式要求
2014/05/09 职场文书
单位承诺书格式
2014/05/21 职场文书
法人委托书
2014/07/31 职场文书
公证处委托书
2015/01/28 职场文书
财务工作个人总结
2015/02/27 职场文书
Springboot集成阿里云OSS上传文件系统教程
2021/06/28 Java/Android
Django框架之路由用法
2022/06/10 Python