JS有哪些变态语法

JS做为一门如此灵活的语言,天然在编码时给咱们带来了不少方便,但方便的同时,也衍生出了不少变态的语法,下面咱们来梳理一些常见的变态语法,但愿你下次在某位大牛的代码中看到这样的东西,不要惊掉下巴。java

  NO.1bootstrap

——————————————————————————————————————数组

  Number.prototype.add = function(n){浏览器

  return this+n;函数

}测试

  2"add"
——————————————————————————————————————this

  最后一句话是什么玩意儿?好像没看懂呢? 咱们来运行一下看看编码

  我擦? 它竟然执行了?结果是5,看上去彷佛对2和3作了加法。prototype

  不是说变量名不能数字开头么?这是怎么回事?浏览器抽风了?对象

  实际上js有不少不能说的秘密,其中一个就叫作自动装箱,这是引用java里的叫法。也就是说,当咱们试图2[“add”]的时候,这个数字2已经再也不是2了,它被自动转换成了Number对象,跟java中的包装类型是一个意思。

等价于这样写:

  new Number(2)

  而对象是能够经过[“prop"]这种形式来获取属性的,因而咱们就不难推理了

  2["add"] 至关于 new Number(2).add

  最终变成

  new Number(2).add(3);

  结果是 5

NO.2

—————————————————————————————————————— +function(){;}()
——————————————————————————————————————

  这又是个什么玩意儿?函数前面带个+号? 这难道是自动类型转换?等等,里面是个;号? 后面还有一对( )?

  先不要着急惊讶,其实还有不少,例如:

  -function(){;}()

  !function(){;}()

  ~function(){;}()

  void function(){;}()

  new function(){;}()

  delete function(){;}()

  var i = function(){;}()

  1 && function(){;}()

  0 || function(){;}()

  1 & function(){;}()

  1 | function(){;}()

  1 ^ function(){;}()

  1, function(){;}()

  我靠!这些丧尽天良的写法是谁发明的?!你给我站出来,我保证不打死你!

  (此处做者冷静了5分钟)

  接下来讲说它的原理吧

  首先 ;号自己也是一条语句,相信大多数同窗应该是知道的,就很少说了。其次,一个函数的自调用,若是写成这样:

  错误的缘由在于,函数声明和函数调用是不能够混在一块儿的,因此一般的写法是:

  这并非把函数当成了一个总体来运行,这里其实还有一个不能说的秘密

  ( )这个符号,在js里是运算符。(A)的结果是返回表达式A

  因此它的出现,让这个匿名函数从声明变成了执行,也就是编译期间浏览器不会提早准备它,天然就没有语法错误。而5分钟前咱们看到的那些丧心病狂的写法,其实原理都同样,经过运算符把声明变成执行。固然这些符号都不会影响函数的正常执行结果。

  可是问题又来了,这种泯灭人性的写法,如今竟然还挺常见的,例如:

  没错,这就是著名的bootstrap的js源码,连它都是这么写的,莫非真有什么好处?

  经过在网上查询大量的资料,我还真发现有人专门对此作了研究,将上面这些写法所有在各个浏览器中间作了压力测试,发现+function( ){;}( ) 执行速度最快,比(function( ){})( )要快出好几倍

  而 new function( ){;}( ) 执行速度最慢。

  不过为了追求效率而把代码写成这样到底值不值,那只能你本身去判断了。

NO.3

——————————————————————————————————————
!!a
——————————————————————————————————————

  这又是什么鬼啊

  !!a 实际上等价于 a || false

  因为js中全部的内容都是能够跟布尔类型互换的,这也是js特别让人费解的地方,好比

  if(window.VBArray){…}

  能够用来判断IE浏览器,由于对象存在时,等价于true,undefined等价于false,可是!不少时候咱们判断一个属性是否存在,并不须要立刻做出反应,而是将结果告知他人,好比说有个函数,test(hasSuperman),函数规定调用时须要传入一个布尔类型,告知它superman是否存在,你可能会这样写:

  if(window.superman){

  test(true);

  } else {

  test(false);

  }

  但你最好不要这么写:

  test(window.superman);

  由于你并不知道test函数内部发生了什么,因此很难预料会不会产生错误,所以最好的写法是这样:

  test(!!window.superman);

  经过两次取反,保证了值没有变化,但类型已经被转为了布尔类型。好吧,彷佛这么写还有点道理。

NO.4 最短IE(6,7,8)断定

————————————————————————————————————— if(!-[1,]){

   //判断IE6,7,8

  }
—————————————————————————————————————

  它的原理其实是利用了IE的bug。

  当咱们写下一个数组 [1,].length

  在IE中 [1,].length -------> 2

  在非IE中 [1,].length -------> 1

  当咱们试图打印[1,],至关于调用toString()方法

  在IE中 [1,] -------> "1,"

  在非IE中 [1,] -------> "1"

  当咱们给它加上负号-[1,]

  在IE中 -[1,] -------> NaN

  在非IE中 -[1,] -------> -1

  当咱们对它进行取反!-[1,]

  在IE中 !-[1,] -------> true

  在非IE中 !-[1,] -------> false

  这样咱们就能够判断是否为IE浏览器了,这个bug一直到IE9以后才消失的。

  好了,此次的变态语法就先讲这么多,之后碰到更新鲜的再来给你们更新,拜拜。

相关文章
相关标签/搜索