起步软件技术论坛
搜索
 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2943|回复: 0

[分享] JavaScript中奇妙的现象

  [复制链接]

242

主题

1418

帖子

2325

积分

金牌会员

批判主义者

Rank: 6Rank: 6

积分
2325
QQ
发表于 2014-5-20 23:51:18 | 显示全部楼层 |阅读模式
版本: 小版本号:
数据库: 服务器操作系统: 应用服务器:
客户端操作系统: 浏览器:
本帖最后由 腹部流出的肉 于 2014-7-7 22:49 编辑

分享一下 知道的勿喷 错了的勿喷 望补充不足 也许有的不是奇怪的    非常零碎

1.alert("【Infinity + Infinity】 =  "+ (Infinity + Infinity) + // Infinity
          "\r\n【Infinity + (-Infinity)】 =  " + (Infinity + (-Infinity)) + //NaN
          "\r\n【-Infinity + (-Infinity)】 =  " + (-Infinity + (-Infinity)) + //-Infinity
          "\r\n【Infinity - Infinity】 = "  + (Infinity - Infinity) + //NaN
          "\r\n【-Infinity - (-Infinity)】 = " + (-Infinity - (-Infinity))  + //NaN
          "\r\n【Infinity - (-Infinity)】 = " + (Infinity - (-Infinity)) + //Infinity
          "\r\n【-Infinity - Infinity】= " + (-Infinity - Infinity) +  //-Infinity
          "\r\n【Infinity * Infinity】= " + (Infinity * Infinity) + //Infinity
          "\r\n【-Infinity * (-Infinity)】= " + (-Infinity * (-Infinity)) + //Infinity
          "\r\n【-Infinity * Infinity】 = " + (-Infinity * Infinity) + //-Infinity
          "\r\n【Infinity / Infinity】= " + (Infinity / Infinity) + // NaN
          "\r\n【-Infinity / - Infinity】 = " + (-Infinity / - Infinity) + //NaN -Infinity / -Infinity = 1 * (Infinity / Infinity) = 1 * NaN = NaN
          "\r\n【Infinity / -Infinity】= " + (Infinity / -Infinity) + //NaN
          "\r\n【-Infinity / Infinity】= " + (-Infinity / Infinity)  + //NaN
          "\r\n【Infinity mod Infinity】= " + (Infinity / Infinity) + //NaN
          "\r\n【-Infinity mod -Infinity 】=" + (-Infinity % (-Infinity)) + //NaN
          "\r\n【Infinity mod -Infinity】=" + (Infinity mod (-Infinity)) + //NaN
          "\r\n【-Infinity mod Infinity】=" + (-Infinity mod Infinity)); //NaN
         至于各中原因:惟妙惟肖,解释不了,求解释。

2.~~~ (-Infintiy)[-Number.MAX_VALUE,-Number.MIN_VALUE] ~~~0 ~~~[Number.MIN_VALUE,Number.MAX_VALUE]~~~(Infintiy)
  Number.MAX_VALUE(正数):1.7976931348623157E+308
  Number.MIN_VALUE(正数):5e-324
  Infinity表示正无穷大的数,而正无穷小的数在Number中没有被表示。
  -Infinity表示负无穷小的数,而负无穷大的数在Number中没有被表示。
  也即-Number.MIN_VALUE,0)和(0,Number.MIN_VALUE)在Number中不能被表示。

3.undefined和NaN和任意数据类型数据进行运算结果为NaN.

4.undefined、null 、true、false、NaN、Infinity、-Infinity、0、""、obj = {valueOf:function {//...},toString(){//...}} 在运算中很微妙

5.//当特殊值作为除数时 undefined NaN Infinity -Infinity 0 true false "" null
//alert(1 / undefined);//NaN
//alert(1 / NaN);//NaN
//alert(1 / Infinity); //0
//alert(-1 / Infinity);// -0 不过(-0和0是一样的 都显示为0)
//alert(0 / Infinity);//0
//alert(-0 / Infinity);//-0 0
//alert(1 / -Infinity);//-0 0
//alert(-1 / -Infinity);//0
//alert(0 / -Infinity);//-0 0
//alert(-0 / -Infinity);//0
//alert(1 / 0);//在Java中会报错,而在JavaScript中没有错误,如果0被作为除数,那么解释器会解释为无穷小正数 Infinity
//alert(-1 / 0);//1 / 无穷小正数得到无穷大正数,加'-'号成为-Infinity
//alert(0 / 0);//当除数和被除数都为0时,0看成无穷小正数或无穷大正数,总之为无穷数,无穷数相除为NaN
//alert(-0 / 0);//NaN
//alert(1 / true);//1
//alert(-1 / true);//-1
//alert(0 / true);//0
//alert(-0 / true);//0
//alert(1 / false);//false被转换为0,0作为除数可看成无穷小正数,结果成了Infinity
//alert( -1 / false);//-Infinity
//alert(0 / false);//false --> 0 ---> 无穷数 NaN
//alert(-0 / false);//NaN
//null和false同运算规律

6.在JavaScript中,如果对象调用没有的属性或方法并不会报错,数组访问没有的元素也并不会报错,而是说undefined,数组没有越界的说法

7.数组兼容性问题

[1,2,3] //好的数组
IE         1,2,3    length 3
firefox   1,2,3    length 3
[1,2,]   //数组丢失了3,因在IE没有容错功能
IE         1,2,      length 3
firefox   1,2       length 2
这样就出现了不一致,这样缺胳膊少腿的数组在不同的浏览器解析不同,不建议这样写   

var arr = [1,2,3,4,5,6];
var arr = [,,,,,];
alert(arr + "|" + arr.length);

8.对象的new操作符创建方式调用了构造函数[Object()],字面量创建方式未调用构造函数[FireFox除外]
   数组的new操作符创建方式调用了构造函数[Array()],字面量创建方式未调用构造函数[FireFox除外]

9.原来数组也是有长度限制:数组最多可包含 4294967295 个元素[一个鬼都不关系的数字],超出即会发生异常。

10.push()和pop()方法是对数组末端操作的栈方法,而unshift()和shift()方法是对数组前端操作的方法
    push() : 在数组的末端添加元素并返回数组的新长度
    pop() : 在数组的末端移除数组的末尾元素并不是返回数组的长度而是返回移除的元素
    unshift() : 在数组的前段添加元素并将数组的新长度返回
    shift() : 在数组的前段移除元素且不是将数组的新长度返回,而是将数组的移除元素返回
    注意 : 其中从数组的前段移除的方法unshift()有兼容性问题,它返回的并不是数组的新长度而是一个奇怪的undefined值,不建议使用;
    然而我在IE8上测试此方法,No Problem
11.sort()reverse()在不传递参数的情况下只能对数组进行适当的排序,什么是适当地排序呢? 就是说它们只能对全部都是一位数的数组进行精确排序,
     如果数组中有两位数以及两位以上的数的元素,那么就在无参数的情况下就不能实现精确排序了,要实现sort()和reverse()方法的精确排序,必须为
     sort()和reverse()传入参数控制它们的精确排序,参数是一个函数对函数的要求
    1.函数参数两个 2.在函数体中比较参数的大小 3.并返回大小值(1,-1,0)[通常为1,-1,0 其实任意数字都是ok的啦... ...]
     var arrObj = [1,22,11,33,28,22,9,10,20];
     function functionName(param1,param2){
     //对于比较后返回的值是任意的(一般返回 1 -1 0),返回正数 : 不交换比较的两个数的位置 0 : 同前 而负数 : 却是会交换两个数的位置
         if(param1 > param2){ //如果第一个数大于第二个数
             return 1;               //看 param1 - param2 > 0 符号和 1同号 正序排序
         }else if(param1 < param2){ //如果第一个数小于第二个数
             return -1;              //看 param1 - param2 < 0 符号和 -1同号 正序排序
         }else{
            return 0;
         }
      } //这个函数名通常为比较 compare
      alert(arrObj.sort(functionName).join("-")); //传入有名函数
      alert(arrObj.sort(function (param1,param2){ //传入匿名函数
          if(param1 > param2){
               return 2;
          }else if(param1 < param2){
               return -2;
          }else{
              return 0;
          }
      }).join("-"));

正序排序:

①.sort();//适当精确
②.sort(function(value1,value2){ //非常精准
if(value1 > value2){
  return 1;
}else if(value1 < value2){
  return -1;
}else{
  return 0;
}
});
③.reverse(function(value1,value2){ //非常精准
if(value1 > value2){
  return -1;
}else if(value1 < value2){
  return 1;
}else{
  return 0;
}
});

逆序排序:

①.reverse();//适当精确
②.sort(function(value1,value2){ //非常精准
if(value1 > value2){
  return -1;
}else if(value1 < value2){
  return 1;
}else{
  return 0;
}
});
③.reverse(function(value1,value2){ //非常精准
if(value1 > value2){
  return 1;
}else if(value1 < value2){
  return -1;
}else{
  return 0;
}
});

总结一下:
排序实现方式
//正序排序 : sort()       sort(compare)  reverse(compare)  sort()
//逆序排序 : reverse()  sort(compare)  reverse(compare)  先sort()  后reverse()

12.详细解说数组对象的slice()splice()方法
     先说一说slice() 和 splice()都是有切片、切取、截取的意思。我查了一下 splice还有“人兽杂交”的意思。
     在ECMAScript方法的调用不关系你给几个参数,它都是可以任你随便调用,能随意调用的函数都是大牛写出来的。
     在关注函数的时候,关注四点:①方法名 ② 参数列表[虽说我们不必关心,但是我们要调用要传递参数,so还是得看看] ③ 返回值 ④ 对调用者的影响
     以var arr = [1,2,3,4,5,6,7,8,9,10];为例
        var newArr = arr.slice();
        var newArr_ = arr.splice();

  1. var arr = [1,2,3,4,5,6,7,8,9,10];
  2. var newArr = arr.slice(); //对原数组复制一份,然后对复制后的数组不切取
  3. alert(typeof newArr + "\r\n" + newArr);//object [1,2,3,4,5,6,7,8,9,10] 且对<FONT color=blue>原始数组没有丝毫影响</FONT>
  4. newArr = arr.slice(1);    //从位置1开始切取,不指定就会切取值到末尾,返回 slice(n)--> [n,arr.length - 1]
  5. newArr = arr.slice(1,2); //从位置1开始切取至第2个位置但不包含位置2,并不是切取2位数 结果为:2 slice(m,n) --> [m,n) 或 [m,n-1]
  6. newArr = arr.slice(1,2,3);//从位置2开始切取值第3个位置不包含3,结果为:3

  7. var newArr_ = arr.splice(); //直接对原数组操作并不复制一份再操作,没有指定怎么切取就表示不截取,返回空数组
  8. newArr_ = arr.splice(1); //从1位置开始切取,没有指定切取多少位,那么直接切取到末尾,返回[2,3,4,5,6,7,8,9,10],原数组就切去了很多元素只剩下[1]
  9. //上面是数组的删除元素
  10. newArr_ = arr.splice(1,2);//从1位置开始切取2个元素而不是切取至第2位,返回[2,3] 原数组[1,4,5,6,7,8,9,10],原数组改变,数组的删除元素newArr_ = arr.splice(1,1);//从1位置开始删除1个元素,数组删除元素,返回[2] 原数组[[1,3,4,5,6,7,8,9,10]
  11. //删除数组某个元素 arr.splice(i,1);//删除第i+1个元素(0 <= i <= arr.length -1)
  12. newArr_ = arr.splice(0,1,22);//前两个参数表示怎么删除,第三个参数表示替补,将1替换成22,实现数组的替换元素
  13. newArr_ = arr.splice(0,0,22);//从0位置开始删除0个就是不删除,后面一个元素就补充在第一个参数指定的位置,实现了数组的添加元素

  14. //通过Array对象的splice()切取方法可是实现数组的增删改
复制代码
13.强大的RegExp对象的方法exec()
    ①.regExp.exec(str); //当exec()执行成功则返回一个数组,否则返回null而非[]
   执行成功
         当正则表达式使用了分组则可能返回多个元素(什么叫使用了分组就是说使用了()),否则返回只有一个数组元素的数组
   第0个元素是整个匹配字符串,第1个元素是第一个子匹配子匹配串
   ... ...
   第i个元素是第i个子匹配对应的子字符串
   返回的数组有属性(普通数组的属性length,input,index,lastIndex)
  ②.input : 存储的是整个匹配字符串
  ③.index : 存储的是匹配字符串的首字母索引
  ④.lastIndex : 存储的是匹配字符串的最后一个字符的下一个位置的索引
  ⑤.如果正则表达式指定了g则是全局正则表达式否则不是全局正则表达式
   不是全局正则表达式调用匹配match() 和 exec() 一样的
   非全局正则表达式调用正则表达式的math()和exec()是一样的结果   
  ⑥.正则表达式没有指定全局修饰符(g),则从index指定的位置进行匹配;否则从lastIndex存储的字符位置开始进行匹配   
   很显然exec()较test()和具有正则表达式匹配的字符串方法复杂很多。
   
特别说明 :  
①.在IE下使用regExpObject的返回后的数组有lastIndex属性值(会被维护)
②.在FF下使用regExpObject的返回后的数组没有lastIndex属性值(不会被维护,则永远为undefined)

regExpTest();

function regExpTest(){ //正则表达式测试
    var str = "The rain in Spain falls mainly in the plain.";
    var regExp = /\w+/;      // /\w/ 表示匹配单个单词 /\W/ 匹配非单个当个单词
    var arr;
document.write(str + "<br/>");
    while ((arr = regExp.exec(str)) != null){ //如果正则表达式没有指定全局则每次从index开始匹配... ... 会出现死循环
       document.write("index:" + arr.index + " lastIndex:" + arr.lastIndex + " arr:" + arr + "<br/>");
}
}
/*
---------------------------
Windows Internet Explorer
---------------------------
停止运行此脚本吗?

此页面上的脚本造成 Web 浏览器运行速度减慢。
如果继续运行,您的计算机将可能
停止响应。

---------------------------
是(Y)   否(N)   
---------------------------
出现了死循环
*/
14.正则表达RegExp和regExpObj的废物属性
/* pattern.test("google google google.");
alert("RegExp.input:" + RegExp.input +
        "\r\nRegExp.index:" + RegExp.index +
        "\r\nRegExp.lastIndex:" + RegExp.lastIndex +
        "\r\nRegExp.lastMatch:" + RegExp.lastMatch + //最后匹配的字符串
        "\r\nRegExp.lastParen:" + RegExp.lastParen +  // 最后一个分组
        "\r\nRegExp.leftContext:" + RegExp.leftContext + //leftContext 最后一次匹配的上一次匹配字符串
        "\r\nRegExp.rightContext:" + RegExp.rightContext +
        "\r\nRegExp.multiline:" + RegExp.multiline); */
/* alert("pattern.global:" + pattern.global +  //true
       "\r\npattern.ignoreCase:" + pattern.ignoreCase +  //true
       "\r\npattern.multiline:" + pattern.multiline + //true
       "\r\npattern.source:" + pattern.source);  //正则表达式中的内容    */

       不管事RegExp的属性input index lastIndex lastMatch lastParen leftContext rightContext multiline 还是regExpObj的global ignoreCase multiline source都是不推荐使用的
15.正则表达式分组()
     1.( 2.( 3.( 4.( 5.( 6.( 7.( 8.( 9.() ) ) ) ) ) ) ) )
     当多个分组嵌套时 RegExp.$1 --> 1 RegExp.$2 --->9
     var pattern = /^(g(o(og)l)e)\$\$\$$/;
     var str = "google$$$";
     alert(pattern.test(str) + "\r\n" + RegExp.$1 + "\r\n" + RegExp.$2 + "\r\n" + RegExp.$3);  

     
     var pattern = /(1(1(2(2(3(3(4(4(5(5(FUCK YOU.)6)6)7)7)8)8)9)9)0)0)/; //共11个分组
     var str = "1122334455FUCK YOU.6677889900";
     pattern.test(str);
     for(var i = 0;i < 9;i++){
         document.write(RegExp.$1 + "<br/>"); //没有RegExp.$i 不存在 undefined
     }


    var pattern = /(.*)\s(\d{4})/;
    var str = "google 2014"; // google (.*) ([a-z]{6}) ([a-z]{6,10}) ([^0-9]*) ([^A-Z]*) ... ...
    var arrObj = pattern.exec(str);
    //alert(arrObj); //arrObj[0] :google 2014,google,2014
    //google 2014,google,2014 字符串数组
    alert(arrObj.length +
           "\r\n" + arrObj[0] +  //返回整个正则表达式模式匹配到的字符串
           "\r\n" + arrObj[1] +  //返回正则表达式模式第一个分组匹配到的字符串
           "\r\n" + arrObj[2]);   //返回正则表达式模式第二个分组匹配到的字符串
   
    var pattern = /.*\s\d{4}/;
    var str = "google 2014";
    alert(pattern.exec(str));//pattern中没有分组 则null或只有一个元素的数组

    pattern 分组:捕获性分组和非捕获性分组
    捕获性分组:在分组的括弧中没有加?:
    非捕获性分组:在分组的括弧前面加了?此时执行pattern.exec(str) 该分组不会被捕获)

    捕获性分组和非捕获性分组的区别就是加没有加?:
    var pattern = /(.*)\s(\d{4})/; //不加?: 捕获性分组
    var str = "google 2014";
    alert(pattern.exec(str));

    看到分组--> 捕获性分组和非捕获性分组--> 分组括弧内前面有无?:   
    var pattern = /(?:.*)\s(\d{4})/; //在第一个分组前面加了?: 这个分组不会被捕获
    var str = "google 2014";
    alert(pattern.exec(str)); // google 2014,2014

    var pattern = /(.*)\s(?:\d{4})/; //在第二个分组前面加了?: 这个分组不会被捕获
    var str = "google 2014";
    alert(pattern.exec(str)); // google 2014,google

    var pattern = /(?:.*)\s(?:\d{4})/; //在第一、二个分组前面加了?: 这个分组不会被捕获
    var str = "google 2014";
    alert(pattern.exec(str)); // google 2014

    用处多多,大家想想吧。。。
待续中... ...







特殊值比较.jpg

评分

参与人数 1 +4 收起 理由
jishuang + 4 赞一个!

查看全部评分

如果我说对了 请别忘记点赞.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|X3技术论坛|Justep Inc.    

GMT+8, 2024-5-18 06:57 , Processed in 0.076711 second(s), 32 queries .

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表