最短的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 相关文章推荐
基于jQuery捕获超链接事件进行局部刷新代码
May 10 Javascript
Jquery动态更改一张位图的src与Attr的使用
Jul 31 Javascript
js string 转 int 注意的问题小结
Aug 15 Javascript
jquery indexOf使用方法
Aug 19 Javascript
js读取被点击次数的简单实例(从数据库中读取)
Mar 07 Javascript
javascript模块化简单解析
Apr 07 Javascript
一起学写js Calender日历控件
Apr 14 Javascript
javascript jquery对form元素的常见操作详解
Jun 12 Javascript
js移动端图片压缩上传功能
Aug 18 Javascript
详解如何在项目中使用jest测试react native组件
Feb 09 Javascript
微信小程序实现留言板
Oct 31 Javascript
JavaScript实现烟花绽放动画效果
Aug 04 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 CKEditor 上传图片实现代码
2009/11/06 PHP
用Zend Studio+PHPnow+Zend Debugger搭建PHP服务器调试环境步骤
2014/01/19 PHP
php 购物车完整实现代码
2014/06/05 PHP
一个图片地址分解程序(用于PHP小偷程序)
2014/08/23 PHP
PHP连接和操作MySQL数据库基础教程
2014/09/29 PHP
Laravel实现短信注册的示例代码
2018/05/29 PHP
善用事件代理,警惕闭包的性能陷阱。
2011/01/20 Javascript
JS实现div内部的文字或图片自动循环滚动代码
2013/04/19 Javascript
JavaScript验证18位身份证号码最后一位正确性的实现代码
2014/08/07 Javascript
jquery单行文字向上滚动效果的实现代码
2014/09/05 Javascript
Javascript动画效果(1)
2016/10/11 Javascript
vue中element组件样式修改无效的解决方法
2018/02/03 Javascript
jQuery实现table表格checkbox全选的方法分析
2018/07/04 jQuery
layui禁用侧边导航栏点击事件的解决方法
2019/09/25 Javascript
解决layui-table单元格设置为百分比在ie8下不能自适应的问题
2019/09/28 Javascript
JS函数进阶之继承用法实例分析
2020/01/15 Javascript
vue 中的 render 函数作用详解
2020/02/28 Javascript
[00:12]2018DOTA2亚洲邀请赛 sylar表现SOLO技艺
2018/04/06 DOTA
用Python的Tornado框架结合memcached页面改善博客性能
2015/04/24 Python
Python2实现的LED大数字显示效果示例
2017/09/04 Python
pandas 使用apply同时处理两列数据的方法
2018/04/20 Python
Python实现常见的回文字符串算法
2018/11/14 Python
Empty test suite.(PyCharm程序运行错误的解决方法)
2018/11/30 Python
django 快速启动数据库客户端程序的方法示例
2019/08/16 Python
python list数据等间隔抽取并新建list存储的例子
2019/11/27 Python
浅谈selenium如何应对网页内容需要鼠标滚动加载的问题
2020/03/14 Python
解决Opencv+Python cv2.imshow闪退问题
2020/04/24 Python
Django修改app名称和数据表迁移方案实现
2020/09/17 Python
Django2.1.7 查询数据返回json格式的实现
2020/12/29 Python
HTML5 script元素async、defer异步加载使用介绍
2013/08/23 HTML / CSS
Casadei卡萨蒂官网:意大利奢侈鞋履品牌
2017/10/28 全球购物
2014党的群众路线教育实践活动总结材料
2014/10/31 职场文书
绵山导游词
2015/02/05 职场文书
2019让人心动的商业计划书
2019/06/27 职场文书
pandas取dataframe特定行列的实现方法
2021/05/24 Python
Windows server 2022创建创建林、域树、子域的步骤
2022/06/25 Servers