最短的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 相关文章推荐
js 编写规范
Mar 03 Javascript
jQuery获取浏览器中的分辨率实现代码
Apr 23 Javascript
jquery对dom的操作常用方法整理
Jun 25 Javascript
关于jquery中全局函数each使用介绍
Dec 10 Javascript
PHP+jQuery+Ajax+Mysql如何实现发表心情功能
Aug 06 Javascript
Sublime Text 3常用插件及安装方法
Dec 16 Javascript
node.js使用cluster实现多进程
Mar 17 Javascript
jquery实现下拉框功能效果【实例代码】
May 06 Javascript
JavaScript用构造函数如何获取变量的类型名
Dec 23 Javascript
利用node.js制作命令行工具方法教程(一)
Jun 22 Javascript
Vue官网todoMVC示例代码
Jan 29 Javascript
Vue的路由及路由钩子函数的实现
Jul 02 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数组操作汇总 php数组的使用技巧
2011/07/17 PHP
PHP版 汉字转码的实现详解
2013/06/09 PHP
ThinkPHP的RBAC(基于角色权限控制)深入解析
2013/06/17 PHP
php多个字符串替换成同一个的解决方法
2013/06/18 PHP
php+mysql实现无限分类实例详解
2015/01/15 PHP
PHP编程中的__clone()方法使用详解
2015/11/27 PHP
PHP基于GD库的图像处理方法小结
2016/09/27 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
javascript document.execCommand() 常用解析
2009/12/14 Javascript
javascript 获取url参数和script标签中获取url参数函数代码
2010/01/22 Javascript
JavaScript中的普通函数与构造函数比较
2015/04/07 Javascript
Bootstrap按钮组件详解
2016/04/26 Javascript
前端js文件合并的三种方式推荐
2016/05/19 Javascript
浅析JavaScript 箭头函数 generator Date JSON
2016/05/23 Javascript
js 动态给元素添加、移除事件的实现方法
2016/07/19 Javascript
jQuery的图片轮播插件PgwSlideshow使用详解
2016/08/11 Javascript
js中的闭包学习心得
2018/02/06 Javascript
使用vuex缓存数据并优化自己的vuex-cache
2018/05/30 Javascript
详解javascript 变量提升(Hoisting)
2019/03/12 Javascript
jQuery实现条件搜索查询、实时取值及升降序排序的方法分析
2019/05/04 jQuery
Vue.js组件使用props传递数据的方法
2019/10/19 Javascript
安装多版本Vue-CLI的实现方法
2020/03/24 Javascript
精确查找PHP WEBSHELL木马的方法(1)
2011/04/12 Python
Python 元组(Tuple)操作详解
2014/03/11 Python
Python压缩和解压缩zip文件
2015/02/14 Python
python pandas 对series和dataframe的重置索引reindex方法
2018/06/07 Python
pyspark.sql.DataFrame与pandas.DataFrame之间的相互转换实例
2018/08/02 Python
详解numpy的argmax的具体使用
2019/05/27 Python
tensorflow 初始化未初始化的变量实例
2020/02/06 Python
html5指南-2.如何操作document metadata
2013/01/07 HTML / CSS
橄榄树药房:OLIVEDA
2019/09/01 全球购物
自我评价优秀范文分享
2013/11/30 职场文书
乡下人家教学反思
2014/02/01 职场文书
餐饮部总监岗位职责范文
2014/02/13 职场文书
格列夫游记读书笔记
2015/07/01 职场文书
python使用glob检索文件的操作
2021/05/20 Python