2009年5月27日

javascript正则表达式是对字符串执行模式匹配的强大工具。正确使用它会给我们的工作带来很大的便利。可是有些地方由于我们没有太注意或者根本不理解,就会遇到不可预料的麻烦。

下面我们要谈谈带有"g" 标记的正则表达式的使用问题,首先让我们看一段代码,从例子入手更容易理解。

1 function a(val) 
2 
3   var re = /^\d+$/g;
4   alert(re.lastIndex);
5   return re.test(val); 
6 
7 alert(a(5)); 
8 alert(a(6));

运行上述代码,在不同浏览器中会得到不同结果,IE中:0 true 0 true,FF和Chrome中:0 true 1 false,看到这里,想必会有人一头雾水,感到诧异。针对这个问题,就我目前查阅资料,找到了两种方法。

1、使用match

  1 function a(val) 

 2 
 3 
 4 
 5   var re = /^\d+$/g;
 6 
 7   if((""+val).match(re))
 8 
 9   return true;
10 
11   else
12 
13   return false;
14 
15 
16 
17 alert(a(5)); 
18 
19 alert(a(6));

注:要使用""+val把val转化为字符串,关于match的具体使用方法可参考这里

2、使用不带"g" 的正则表达式(var re=/^\d+$/或var re=new RegExp("^[0-9]+$"))

 1 function a(val) 
 2 
 3 
 4 
 5   var re = new RegExp("^[0-9]+$");//或者var re=/^\d+$/;
 6 
 7   return re.test(val); 
 8 
 9 
10 
11 alert(a(5)); 
12 
13 alert(a(6)); 
14 
15 

注:var re = new RegExp("^[0-9]+$")中只能用[0-9],不能用\d,至于为什么,我不很明白,希望哪位知道的给讲讲。

不难看出,上面两种方法是从侧面考虑怎么解决问题 的,没有从正面解决,接下来我们从问题出现的本质上分析一下,并给出解决方法。

要从问题出现的本质考虑,我们就不得不从"g" 标记说起,带有"g"标记的正则表达式有一个属性lastIndex,该属性存放一个整数,它声明的是上一次匹配文本之后的第一个字符的位置。上次匹配的结果是由方法 RegExp.exec() 和 RegExp.test() 找到的,它们都以 lastIndex 属性所指的位置作为下次检索的起始点。这样,就可以通过反复调用这两个方法来遍历一个字符串中的所有匹配文本。该属性是可读可写的。只要目标字符串的下一次搜索开始,就可以对它进行设置。当方法 exec() 或 test() 再也找不到可以匹配的文本时,它们会自动把 lastIndex 属性重置为 0。看到这里我们不难看出问题出现的原因和解决方法了,只要我们在下次搜索之前把lastIndex属性重置为0即可,如下:

 1 function a(val) 
 2 
 3 
 4 
 5   var re = /^\d+$/g;
 6 
 7   re.lastIndex=0;//重置lastIndex为0
 8 
 9   return re.test(val); 
10 
11 
12 
13 alert(a(5)); 
14 
15 alert(a(6)); 

关于lastIndex的更多解释请看这里

 至此我们已经明白问题出现的本质,以及如何较好的解决这样的问题,希望本文对一些人有帮助。

 

posted @ 2009-05-27 23:37 奋斗的小涛 阅读(577) 评论(5) 编辑
 

今天看了一段javascript代码,如下:

 1      var i = 1;
 2 
 3       function Test() {
 4 
 5         var aa = 33;
 6 
 7         i = i + 1;
 8 
 9         for (var i = 0; i < 3; i++) {
10 
11           aa = aa + i;
12 
13           for (var i = 0; i < 3; i++) {
14 
15             aa = aa + i;
16 
17           }
18 
19         }
20 
21         alert(aa);//36
22 
23         alert(i);//4
24 
25       }
26 
27       Test();
28 

29       alert(i); //1 

感觉挺迷惑的,于是便放到本地调了调,发现这段代码有很多问题。 其中定义了三个变量,都叫i,并且还有一个循环,里面又嵌了一个循环,想必有人看到后都有点模棱两可的感觉。运行这段代码,执行的结果如下(注释所示):

36

4

1 

 

接下来是我的一些理解和看法。

首先,test()函数中的“ i = i + 1;”是多余的,因为test()函数里定义了变量i并且是在这行代码后面赋的值0,其实此时i还未定义,所以这行代码是可以删除的。

其次,test()函数里定义的两个i,让我看来是同一个变量,外层循环其实只进行了一次,内层循环进行三次后,aa值变成了36,i值变成了3,返回到外层循环后,i值加1,即变成了4 ,最后一个输出1是全局变量i,即第一个变量i的值。

本人也是从实践和猜测得出上面的一些结论的,可能什么地方说的不对或者言辞不当,还请各位批评指正,也请大家说说自己的看法。

 

posted @ 2009-05-27 16:54 奋斗的小涛 阅读(86) 评论(2) 编辑

2009年5月23日

      最近在项目中写了一个验证数字的正则表达式/^(([1-9][0-9]{0,2}(,\d{3})+)|([1-9]\d*)|0)(.\d{1,4})?$/,接下来我先讲讲我使用这个表达式的本意。

      我们分四步讲一下:

      1、[1-9][0-9]{0,2}(,\d{3})+

上式用于匹配以逗号","分割的整数,如1,111,111或11,111,111或111,111,111等等。

      2、[1-9]\d*

上式不用多讲了吧,就是匹配非零的整数

      3、0

这个更不用讲了,就是0呗,呵呵

      4、.\d{1,4}

这个匹配1到4位小数部分。现在看不出来这里有什么问题吧,嘿嘿,别急,接下来我要讲的问题就出在这里。

      综上所述,整个表达式就是匹配以逗号分割的整数、一般的非零整数、零以及各自的小数形式。原本以为这里不会出什么问题,可结果却不像我想的那样,经产品部测试发现这里有一个bug,就是10*11也能验证通过,不应该啊,反复考虑也想不明白,后来在网上搜了搜,终于找到了问题所在,原来点号"."在正则表达式中匹配任何一单个的字符而不管该字符是什么,所以才出现了上面的结果,要想只匹配点号应该使用转义符号"\"进行转义即可,正确的验证表达式应该是/^(([1-9][0-9]{0,2}(,\d{3})+)|([1-9]\d*)|0)(\.\d{1,4})?$/但是记住点号”.“在一个字符集中如[./-]就不是匹配任何字符了,此时他只匹配点号。

     上面是我在学习Javascript过程中的一点心得,很高兴和大家分享,大家不要笑话我啊,我javascript入门还不久呢,嘿嘿

posted @ 2009-05-23 14:23 奋斗的小涛 阅读(193) 评论(2) 编辑

2009年5月20日

转自w3school

ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。

typeof 运算符

typeof 运算符有一个参数,即要检查的变量或值。例如:

var sTemp = "test string";
alert (typeof sTemp);    //输出 "string"
alert (typeof 86);    //输出 "number"

对变量或值调用 typeof 运算符将返回下列值之一:

  • undefined - 如果变量是 Undefined 类型的
  • boolean - 如果变量是 Boolean 类型的
  • number - 如果变量是 Number 类型的
  • string - 如果变量是 String 类型的
  • object - 如果变量是一种引用类型或 Null 类型的

注释:您也许会问,为什么 typeof 运算符对于 null 值会返回 "Object"。这实际上是 JavaScript 最初实现中的一个错误,然后被 ECMAScript 沿用了。现在,null 被认为是对象的占位符,从而解释了这一矛盾,但从技术上来说,它仍然是原始值。

Undefined 类型

如前所述,Undefined 类型只有一个值,即 undefined。当声明的变量未初始化时,该变量的默认值是 undefined。

var oTemp;

前面一行代码声明变量 oTemp,没有初始值。该变量将被赋予值 undefined,即 undefined 类型的字面量。可以用下面的代码段测试该变量的值是否等于 undefined:

var oTemp;
alert(oTemp == undefined);

这段代码将显示 "true",说明这两个值确实相等。还可以用 typeof 运算符显示该变量的值是 undefined:

var oTemp;
alert(typeof oTemp); //输出 "undefined"

提示:值 undefined 并不同于未定义的值。但是,typeof 运算符并不真正区分这两种值。考虑下面的代码:

var oTemp;
alert(typeof oTemp);  //输出 "undefined"
alert(typeof oTemp2);  //输出 "undefined"

前面的代码对两个变量输出的都是 "undefined",即使只有变量 oTemp2 从未被声明过。如果对 oTemp2 使用除 typeof 之外的其他运算符的话,会引起错误,因为其他运算符只能用于已声明的变量上。

例如,下面的代码将引发错误:

var oTemp;
alert(oTemp2 == undefined);

当函数无明确返回值时,返回的也是值 "undefined",如下所示:

function testFunc() {
}
alert(testFunc() == undefined);  //输出 "true"

Null 类型

另一种只有一个值的类型是 Null,它只有一个专用值 null,即它的字面量。值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的。

alert(null == undefined);  //输出 "true"

尽管这两个值相等,但它们的含义不同。undefined 是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示尚未存在的对象(在讨论 typeof 运算符时,简单地介绍过这一点)。如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。

Boolean 类型

Boolean 类型是 ECMAScript 中最常用的类型之一。它有两个值 true 和 false (即两个 Boolean 字面量)。

即使 false 不等于 0,0 也可以在必要时被转换成 false,这样在 Boolean 语句中使用两者都是安全的。

var bFound = true;
var bLost = false;

Number 类型

ECMA-262 中定义的最特殊的类型是 Number 类型。这种类型既可以表示 32 位的整数,还可以表示 64 为的浮点数。

直接输入的(而不是从另一个变量访问的)任何数字都被看做 Number 类型的字面量。例如,下面的代码声明了存放整数值的变量,它的值由字面量 86 定义:

var iNum = 86;

八进制数和十六进制数

整数也可以被表示为八进制(以 8 为底)或十六进制(以 16 为底)的字面量。八进制字面量的首数字必须是 0,其后的数字可以是任何八进制数字(0-7),如下面的代码所示:

var iNum = 070;  //070 等于十进制的 56

要创建十六进制的字面量,首位数字必须为 0,后面接字母 x,然后是任意的十六进制数字(0 到 9 和 A 到 F)。这些字母可以是大写的,也可以是小写的。例如:

var iNum = 0x1f;  //0x1f 等于十进制的 31
var iNum = 0xAB;  //0xAB 等于十进制的 171

提示:尽管所有整数都可以表示为八进制或十六进制的字面量,但所有数学运算返回的都是十进制结果。

浮点数

要定义浮点值,必须包括小数点和小数点后的一位数字(例如,用 1.0 而不是 1)。这被看作浮点数字面量。例如:

var fNum = 5.0;

对于浮点字面量的有趣之处在于,用它进行计算前,真正存储的是字符串。

科学计数法

对于非常大或非常小的数,可以用科学计数法表示浮点数,可以把一个数表示为数字(包括十进制数字)加 e(或 E),后面加乘以 10 的倍数。例如:

var fNum = 5.618e7

该符号表示的是数 56180000。把科学计数法转化成计算式就可以得到该值:5.618 x 107

也可以用科学计数法表示非常小的数,例如 0.00000000000000008 可以表示为 8-e17(这里,10 被升到 -17 次冥,意味着需要被 10 除 17 次)。ECMAScript 默认把具有 6 个或 6 个以上前导 0 的浮点数转换成科学计数法。

提示:也可用 64 位 IEEE 754 形式存储浮点值,这意味着十进制值最多可以有 17 个十进制位。17 位之后的值将被裁去,从而造成一些小的数学误差。

特殊的 Number 值

几个特殊值也被定义为 Number 类型。前两个是 Number.MAX_VALUE 和 Number.MIN_VALUE,它们定义了 Number 值集合的外边界。所有 ECMAScript 数都必须在这两个值之间。不过计算生成的数值结果可以不落在这两个值之间。

当计算生成的数大于 Number.MAX_VALUE 时,它将被赋予值 Number.POSITIVE_INFINITY,意味着不再有数字值。同样,生成的数值小于 Number.MIN_VALUE 的计算也会被赋予值 Number.NEGATIVE_INFINITY,也意味着不再有数字值。如果计算返回的是无穷大值,那么生成的结果不能再用于其他计算。

事实上,有专门的值表示无穷大,(如你猜到的)即 Infinity。Number.POSITIVE_INFINITY 的值为 Infinity。Number.NEGATIVE_INFINITY 的值为 -Infinity。

由于无穷大数可以是正数也可以是负数,所以可用一个方法判断一个数是否是有穷的(而不是单独测试每个无穷数)。可以对任何数调用 isFinite() 方法,以确保该数不是无穷大。例如:

var iResult = iNum * some_really_large_number;
if (isFinite(iResult)) {
alert("finite");
}
else {
alert("infinite");
}

最后一个特殊值是 NaN,表示非数(Not a Number)。NaN 是个奇怪的特殊值。一般说来,这种情况发生在类型(String、Boolean 等)转换失败时。例如,要把单词 blue 转换成数值就会失败,因为没有与之等价的数值。与无穷大一样,NaN 也不能用于算术计算。NaN 的另一个奇特之处在于,它与自身不相等,这意味着下面的代码将返回 false:

alert(NaN == NaN);  //输出 "false"

出于这个原因,不推荐使用 NaN 值本身。函数 isNaN() 会做得相当好:

alert(isNaN("blue"));  //输出 "true"
alert(isNaN("666"));  //输出 "false"

String 类型

String 类型的独特之处在于,它是唯一没有固定大小的原始类型。可以用字符串存储 0 或更多的 Unicode 字符,有 16 位整数表示(Unicode 是一种国际字符集,本教程后面将讨论它)。

字符串中每个字符都有特定的位置,首字符从位置 0 开始,第二个字符在位置 1,依此类推。这意味着字符串中的最后一个字符的位置一定是字符串的长度减 1:

字符串的长度和字符的位置

字符串字面量是由双引号(")或单引号(')声明的。而 Java 则是用双引号声明字符串,用单引号声明字符。但是由于 ECMAScript 没有字符类型,所以可使用这两种表示法中的任何一种。例如,下面的两行代码都有效:

var sColor1 = "red";
var sColor2 = 'red';

String 类型还包括几种字符字面量,Java、C 和 Perl 的开发者应该对此非常熟悉。

下面列出了 ECMAScript 的字符字面量:

字面量含义
\n 换行
\t 制表符
\b 空格
\r 回车
\f 换页符
\\ 反斜杠
\' 单引号
\" 双引号
\0nnn 八进制代码 nnn 表示的字符(n 是 0 到 7 中的一个八进制数字)
\xnn 十六进制代码 nn 表示的字符(n 是 0 到 F 中的一个十六进制数字)
\unnnn 十六进制代码 nnnn 表示的 Unicode 字符(n 是 0 到 F 中的一个十六进制数字)
posted @ 2009-05-20 14:18 奋斗的小涛 阅读(126) 评论(0) 编辑

2009年5月18日

转自梦之都

什么是BOM

  • BOM是browser object model的缩写,简称浏览器对象模型
  • BOM提供了独立于内容而与浏览器窗口进行交互的对象
  • 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对象是window
  • BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性
  • BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C
  • BOM最初是Netscape浏览器标准的一部分

在BOM章节中你将学到什么

BOM教程中,同学们将学到与浏览器窗口交互的一些对象,例如可以移动,调整浏览器大小的window对象,可以用于导航的location对象与history对象,可以获取浏览器,操作系统与用户屏幕信息的navigator与screen对象,可以使用document作为访问HTML文档的入口,管理框架的frames对象等

BOM结构图

什么是BOM

window对象是BOM的顶层(核心)对象,所有对象都是通过它延伸出来的,也可以称为window的子对象。

由于window是顶层对象,因此调用它的子对象时可以不显示的指明window对象,例如下面两行代码是一样的:

示例

document.write("www.dreamdu.com");
window.document.write("www.dreamdu.com");
posted @ 2009-05-18 21:08 奋斗的小涛 阅读(229) 评论(0) 编辑