最短的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 10 Javascript
固定表格行列(expression)在IE下适用
Jul 25 Javascript
angular简介和其特点介绍
Jan 29 Javascript
javascript白色简洁计算器
May 04 Javascript
js实现商城星星评分的效果
Dec 29 Javascript
node.js 中国天气预报 简单实现
Jun 06 Javascript
jQuery.cookie.js使用方法及相关参数解释
Mar 06 Javascript
深入对Vue.js $watch方法的理解
Mar 20 Javascript
Webpack 4.x搭建react开发环境的方法步骤
Aug 15 Javascript
Vue监听页面刷新和关闭功能
Jun 20 Javascript
Vue的props父传子的示例代码
May 20 Javascript
Vue路由权限控制解析
Nov 09 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根据传入参数合并多个JS和CSS文件的简单实现
2014/06/13 PHP
PHP判断一个gif图片是否为动态图片的方法
2014/11/19 PHP
linux下为php添加iconv模块的方法
2016/02/28 PHP
curl 出现错误的调试方法(必看)
2017/02/13 PHP
ASP.NET jQuery 实例16 通过控件CustomValidator验证RadioButtonList
2012/02/03 Javascript
关于scrollLeft,scrollTop的浏览器兼容性测试
2013/03/19 Javascript
JS验证控制输入中英文字节长度(input、textarea等)具体实例
2013/06/21 Javascript
javascript日期操作详解(脚本之家整理)
2015/09/05 Javascript
javascript使用 concat 方法对数组进行合并的方法
2016/09/08 Javascript
form表单转Json提交的方法(推荐)
2016/09/23 Javascript
AngularJS自定义指令详解(有分页插件代码)
2017/06/12 Javascript
bootstrapvalidator之API学习教程
2017/06/29 Javascript
Vue.js2.0中的变化小结
2017/10/24 Javascript
js数组常用最重要的方法
2018/02/04 Javascript
JS精确判断数据类型代码实例
2019/12/18 Javascript
ES6箭头函数和扩展实例分析
2020/05/23 Javascript
Vue点击切换Class变化,实现Active当前样式操作
2020/07/17 Javascript
[05:49]2014DOTA2TI4正赛第二日综述 昔日冠军纷纷落马 VG LGD占尽先机
2014/07/20 DOTA
python对html代码进行escape编码的方法
2015/05/04 Python
Python的Django框架中设置日期和字段可选的方法
2015/07/17 Python
Python3使用requests登录人人影视网站的方法
2016/05/11 Python
python实现手机通讯录搜索功能
2018/02/22 Python
PyCharm+PySpark远程调试的环境配置的方法
2018/11/29 Python
Python 实现微信防撤回功能
2019/04/29 Python
微信小程序“圣诞帽”的实现思路详解
2017/12/28 HTML / CSS
amazeui树节点自动展开折叠面板并选中第一个树节点的实现
2020/08/24 HTML / CSS
询价采购方案
2014/06/09 职场文书
普通员工辞职信范文
2015/05/12 职场文书
运动会广播稿200字
2015/08/19 职场文书
如何书写民事调解协议书?
2019/06/25 职场文书
Python基础之pandas数据合并
2021/04/27 Python
Redis6.0搭建集群Redis-cluster的方法
2021/05/08 Redis
浅谈哪个Python库才最适合做数据可视化
2021/06/28 Python
Nginx 路由转发和反向代理location配置实现
2021/11/11 Servers
Win7/8.1用户可以免费升级到Windows 11系统吗?
2021/11/21 数码科技
MybatisPlus EntityWrapper如何自定义SQL
2022/03/22 Java/Android