为了账号安全,请及时绑定邮箱和手机立即绑定

用最短AJAX创建代码

  假如你的脚本只针对某个浏览器开发,那么创建XMLHTTP是很简单的一件事,用XMLHttpRequest或者ActiveXObject即可。但事实上绝大多数的时候,我们都要考虑兼容,于是我们通常写成:

var x;
if(window.ActiveXObject)
    x = new ActiveXObject("Microsoft.XMLHTTP");
else
    x = new XMLHttpRequest();

 

  当然,熟练的朋友更倾向于简练的代码:

var x = window.ActiveXObject?
        new ActiveXObject("Microsoft.XMLHTTP"):
        new XMLHttpRequest();

  但也到此而已。这段代码还能继续压缩吗?我们不妨来探索下。

  

  现在我们把一堆单词: ActiveXObject,  "Microsoft.XMLHTTP", XMLHttpRequest, window 配上几个符号重新排列起来,组合出一个语法正确并且能正常运行的表达式。

 

  首先我们最容易想到的就是共用一个new。因为JS里面有个很强大的运算符“||”,相信大家都用过。所以我们先用||得出Class,然后用new实例化出instance。于是:

new (window.XMLHttpRequest || ActiveXObject("Microsoft.XMLHTTP"))

 

  很不幸,它没能通过IE6,7的考验。(IE8+已经支持XMLHttpRequest了)

   

  错误很简单,就在ActiveXObject("Microsoft.XMLHTTP")上。Automation 服务器不能创建对象。 


  在IE里,ActiveXObject(...)之前必须带上new,否则就会出现上面的错误。但请注意了,ActiveXObject后面是带参数调用的。如果我们单独引用ActiveXObject这个函数,然后再实例化,结果会如果呢?我们测试下:

var ref = ActiveXObject;
var x = new ref("Microsoft.XMLHTTP");

x.open("GET", "1.html", true);
x.send();
alert(x.responseText)

  结果不但没有报错,并且成功的显示出了文字。这说明window.ActiveXObject这个方法是可以引用调用,但必须用new才能创建组建。这很好理解:function ActiveXObject(){}的Native Code会判断当前是new call还是direct call,如果不是new call就报错。这意味着你不能预先创建出XMLHTTP的Class,而必须用ActiveXObject的工厂形式。

  

  既然事实如此,我们只能用XMLHttpRequest || ActiveXObject这样的逻辑。如果带上new,我们就得到这样的代码:

new (window.XMLHttpRequest || ActiveXObject)

  这对XHR的创建已经够了,但是ActiveX还需要提供一个参数指定组件名。这个参数加在哪里好呢?不用多虑,就放在最后!

   

  因为XMLHttpRequest的构造函数是不带参数的,而JS是个弱类型语言,所以你即便给他指定一个参数也不会出问题。于是最后,我们用一行表达式即可创建:

new (window.XMLHttpRequest || ActiveXObject)("Microsoft.XMLHTTP")

  
  因为IE8+即支持 XMLHttpRequest 和 ActiveXObject,因此上面 || 左右顺序决定了IE8+优先使用哪种。

    

  不过,这还不是最简短的!没错,还有更精简的,但显得不是特别正规,甚至有点晦涩。

   

  纵观上述代码,其中的window显得有点多余,但又不能去掉。假如有个简单的办法判断是(或者不是)IE浏览器,我们就可以用 ?: 运算符来代替 || 了。

 

  曾经有个老外写过最简短判断IE的办法,只需6个字节 !-[1,]  原理就是IE特有的特征,数组处理最后项的bug。利用这个办法,我们还可以进一步压缩代码:

new(-[1,]?XMLHttpRequest:ActiveXObject)("Microsoft.XMLHTTP")

  
  无疑,这是最简短的XMLHTTP创建代码了!正好60个字节。 但相比规范性和可读性,还是推荐之前那种。

  

  补充:感谢经典论坛上的crimsonet网友提醒,其实用self对象完全可以代替window。self是window的只读属性,并且永远指向window,所以用:

new(self.XMLHttpRequest||ActiveXObject)("Microsoft.XMLHTTP")

  

  也正好是60字节,并且更规范:)

  (如果不是在内嵌框架里运行的话,top===window,还能-1。在框架内top引用顶层窗体,当然会有问题的了)

 

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消