最短的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给input和textarea设定ie中的focus
May 29 Javascript
jQuery 下拉列表 二级联动插件分享
Mar 29 Javascript
Javascript中常见的校验如域名、手机、邮箱等等
Jan 02 Javascript
总结JavaScript中布尔操作符||与&amp;&amp;的使用技巧
Nov 17 Javascript
JS中的==运算: [''] == false —&gt;true
Jul 24 Javascript
AngularJS变量及过滤器Filter用法分析
Nov 22 Javascript
JS闭包用法实例分析
Mar 27 Javascript
老生常谈combobox和combotree模糊查询
Apr 17 Javascript
jQuery获取table表中的td标签(实例讲解)
Jul 28 jQuery
你可能不知道的CORS跨域资源共享
Mar 13 Javascript
JavaScript怎样在删除前添加确认弹出框?
May 27 Javascript
js实现二级联动简单实例
Jan 11 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
PHP4与PHP5的时间格式问题
2008/02/17 PHP
PHP学习笔记之数组篇
2011/06/28 PHP
Zend的MVC机制使用分析(一)
2013/05/02 PHP
php图像处理函数大全(推荐收藏)
2013/07/11 PHP
php cli换行示例
2014/04/22 PHP
PHP正则表达式 /i, /is, /s, /isU等介绍
2014/10/23 PHP
PHP简单遍历对象示例
2016/09/28 PHP
PHP编程实现脚本异步执行的方法
2017/08/09 PHP
Gambit vs ForZe BO3 第二场 2.13
2021/03/10 DOTA
文本加密解密
2006/06/23 Javascript
JQuery 选项卡效果(JS与HTML的分离)
2010/04/01 Javascript
js利用与或运算符优先级实现if else条件判断表达式
2010/04/15 Javascript
input标签内容改变的触发事件介绍
2014/06/18 Javascript
Nodejs+express+html5 实现拖拽上传
2014/08/08 NodeJs
JavaScript中的Math.LN2属性用法详解
2015/06/12 Javascript
JS实现的打字机效果完整实例
2016/06/20 Javascript
Node.js数据库操作之连接MySQL数据库(一)
2017/03/04 Javascript
Vue的事件响应式进度条组件实例详解
2018/02/04 Javascript
JS实现的简单下拉框联动功能示例
2018/05/11 Javascript
使用vue实现HTML页面生成图片的方法
2020/03/12 Javascript
浅谈JS for循环中使用break和continue的区别
2020/07/21 Javascript
layui使用及简单的三级联动实现教程
2020/12/01 Javascript
Python统计日志中每个IP出现次数的方法
2015/07/06 Python
TensorFlow如何实现反向传播
2018/02/06 Python
Pandas读取并修改excel的示例代码
2019/02/17 Python
详解Python 函数如何重载?
2019/04/23 Python
python多线程http压力测试脚本
2019/06/25 Python
python字符串格式化方式解析
2019/10/19 Python
手把手教你用纯css3实现轮播图效果实例
2017/05/04 HTML / CSS
英国领先的电动可调床制造商:Laybrook
2019/12/26 全球购物
公司承诺书怎么写
2014/05/24 职场文书
早读课迟到检讨书
2014/09/25 职场文书
给领导的感谢信范文
2015/01/23 职场文书
2016暑期社会实践新闻稿
2015/11/25 职场文书
2016入党积极分子党校培训心得体会
2016/01/06 职场文书
新学期小学班主任工作计划
2019/06/21 职场文书