最短的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中奇葩的假值示例应用
Mar 11 Javascript
jQuery插件StickUp实现网页导航置顶
Apr 12 Javascript
jquery使用经验小结
May 20 Javascript
逐一介绍Jquery data()、Jquery stop()、jquery delay()函数(详)
Nov 04 Javascript
AngularJs ng-repeat 嵌套如何获取外层$index
Sep 21 Javascript
BootStrap框架个人总结(bootstrap框架、导航条、下拉菜单、轮播广告carousel、栅格系统布局、标签页tabs、模态框、菜单定位)
Dec 01 Javascript
jquery代码规范让代码越来越好看
Feb 03 Javascript
React Native模块之Permissions权限申请的实例相机
Sep 28 Javascript
基于Vue渲染与插件的加载顺序的问题详解
Mar 05 Javascript
聊聊JS动画库 Velocity.js的使用
Mar 13 Javascript
详解JavaScript作用域和作用域链
Mar 19 Javascript
JS中超越现实的匿名函数用法实例分析
Jun 21 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 ajax 异步执行不等待执行结果的处理方法
2015/05/27 PHP
Highslide.js是一款基于js实现的网页中图片展示插件
2020/03/30 Javascript
js获得鼠标的坐标值的方法
2013/03/13 Javascript
JS版的date函数(和PHP的date函数一样)
2014/05/12 Javascript
JavaScript strike方法入门实例(给字符串加上删除线)
2014/10/17 Javascript
jquery实现简单的无缝滚动
2015/04/15 Javascript
使用AngularJS处理单选框和复选框的简单方法
2015/06/19 Javascript
跟我学习javascript的undefined与null
2015/11/17 Javascript
学习JavaScript设计模式(单例模式)
2015/11/26 Javascript
js实现一个猜数字游戏
2017/03/31 Javascript
基于JSON数据格式详解
2017/08/31 Javascript
vue中eventbus被多次触发以及踩过的坑
2017/12/02 Javascript
vue.js整合vux中的上拉加载下拉刷新实例教程
2018/01/09 Javascript
微信小程序仿知乎实现评论留言功能
2018/11/28 Javascript
Node.js系列之安装配置与基本使用(1)
2019/08/30 Javascript
nuxt配置通过指定IP和端口访问的实现
2020/01/08 Javascript
vue实现简单瀑布流布局
2020/05/28 Javascript
Vue+Element自定义纵向表格表头教程
2020/10/26 Javascript
[04:11]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/01/30 DOTA
[00:36]TI7不朽珍藏III——斯温不朽展示
2017/07/15 DOTA
基于asyncio 异步协程框架实现收集B站直播弹幕
2016/09/11 Python
python向已存在的excel中新增表,不覆盖原数据的实例
2018/05/02 Python
Pycharm设置去除显示的波浪线方法
2018/10/28 Python
详解python使用turtle库来画一朵花
2019/03/21 Python
浅谈django 重载str 方法
2020/05/19 Python
python实例化对象的具体方法
2020/06/17 Python
Python中lru_cache的使用和实现详解
2021/01/25 Python
查找廉价航班和发现新目的地:Kiwi.com
2019/02/25 全球购物
三星法国官方网站:Samsung法国
2019/10/31 全球购物
销售顾问岗位职责
2014/02/25 职场文书
《蒲公英》教学反思
2014/02/28 职场文书
陈安之励志演讲稿
2014/08/21 职场文书
2015年五四青年节演讲稿
2015/03/18 职场文书
2016庆祝国庆67周年宣传语
2015/11/25 职场文书
Python如何利用正则表达式爬取网页信息及图片
2021/04/17 Python
浅谈redis整数集为什么不能降级
2021/07/25 Redis