Javascript 类型转换

Javascript (ECMA Script)是一种弱类型的语言。这并不意味着它没有数据类型,只是变量或者Javascript对象属性不需要一个特定类型的值分配给它或者它始终使用相同的值。Javascript中的变量同样支持自由类型转换成为适用(或者要求)的内容以便于使用。

弱类型的Javascript不会按照程序员的愿望从实际的变量类型到所需要的数据类型转换,例如一个非常常见的错误,在浏览器脚本中,从表单控件中获取用户将要输入的一个数值类型的变量与另一个数值变量的和。因为变量类型在表单控件中是字符串类型(计时字符串序列包含一个数字)这种尝试将会添加那个字符串到变量,即使这些值碰巧是一些数字,结果在第二个变量将会被转换为字符串类型,在最后只会把从表单控件中得到的变量添加到第一个字符串末尾。
转换到布尔类型

当表达式是 if 以及其他一些判断情况时,类型转换的结果将会是布尔型为了用于判断。这些判断包括逻辑运算比如 与 (&&), 或 (||) 以及 非 (!)。 非运算转换变量为波尔型并且如果变量是波尔型-真。那么将返回假,反之将返回真。两次非操作将会返回等同于变量转换成为波尔型的值。

var boolValue = !!x;

这个技巧将会后面将会用到。

另外一种可选择的方法就是把目标作为参数传递给Boolean 构造函数。

var boolValue = Boolean(x);

(1) 当数值类型转换为布尔型时,数值零将会变成假而其他数值将会变成真。除开特殊数值 NaN (Not a Number),NaN 被用于其他类型转换到数值类型时当没有返回一个有意义的数值时。NaN 总是返回假。 无论是无限大还是无限小或者是有限数值,只要不是零,在转换为布尔型时总是返回true。

(2) 字符串类型转换规则是简单的,字符串类型转换到布尔型除了空字符串外都是返回真,空字符串返回假。

(3) 对于其他类型,undefined 和 null 将会返回假,Object以及function类型总是返回真。

当需要判断某一对象是否是未定义的对象时,这是最有价值的功能。如果调用未定义的变量(undefined 或者 null) 将会产生错误。当这些都还不确定时(通常是网页浏览器所关心的)为了避免代码产生错误,需要对对象进行 if 判断。建议把对象作为表达式,转换为波尔型,如果返回 false 则说明对象不存在,如果返回 true 则说明对象存在。

if(document.documentElement){

scrollX = document.documentElement.scrollLeft;

}

两次非操作可以判断对象是否能被使用。

var hasDocEl = !!document.documentElement;

...

if(hasDocEl){

scrollX = document.documentElement.scrollLeft;

}

转换到字符串类型

如上文所说的,其他类型转换到字符串类型常常来自于 + 操作符,无论其中一个参数是否为数值。最简单转换到字符串的方法是,把目标变量连接到一个空字符串上。这种技巧的结果对应如下表:

另外一种可选择的方法就是把目标作为参数传递给 String 构造函数。

var stringValue = String(x);

注意上面数值 123e-2 已经被转换为字符串 "1.23" ,因为已经由科学计数法转换为普通表达式了。然而,Javascript 的本质数值类型是来自于IEEE的双精度浮点类型,这就意味着只能储存有限的精度。数学操作结果可能只能产生近似的值。当他们转换到字符串时,可能会收到意想不到(指坏的)的结果。所以常常需要设置特定的定制函数用以获得可接受的结果。这种类型转换机制难以保证正常结果。

当一个对象或者函数被转换为字符串时,他们的 toString 方法将会被调用。默认会执行 Object.prototype.toString 以及Function.prototype.toString 除 除非重写 "toString" 方法。把一个函数转换到字符串,返回结果并非是必须的.Function.prototype.toString 方法就能完成大部分需要,它将会返回 "host objects" 和方法(这个对象和方法取决于不同环境,比如 DOM 元素)。

 转换到数值型

转换到数值类型,特别是由字符串转换到数值类型,有很多通用的方法,任何数学操作方法除了加法( + )都会执行类型转换。所以转换字符串类型到数值类型可以使之与一个数值操作,比如减去零或者乘以一。

var numValue = stringValue - 0;

/* or */

var numValue = stringValue * 1;

/* or */

var numValue = stringValue / 1;

但是 + (取正)操作还是可以转换字符串类型到数值类型。因为他不做任何计算操作,所以这种方法是最快的。

顺便一提,相反数操作 - 同样也会执行类型转换,使得目标成为相反的结果。

var numValue = (+stringValue);

/* 这是不必要的,在 + 操作后已经被添加了括弧,只是为了使得代码更容易被人理解并且使得他很清楚,特别是避免了与添加和连续操作相混淆。

+ (取正)操作是最快的转换字符串类型到数值类型的方法。传递给 Number 构造函数一个参数,它将会执行类型转换并且返回一个数值类型。
var numValue = Number(stringValue);
Number构造函数是最慢的类型转换方法,但是当速度不是所考虑的关键时,使用它能够使得代码变得很干净。

对于其他类型,Objects 和 functions 总是被转换为 NaN 。undefined 与 null 同样代表没有东西,但是只有 null 被转换为数值零。可能是因为他们先被转换为波尔型,然后才转换为数值型,在上文中转换为波尔型的结果已经很清楚了, null 转换为波尔型将会返回 false 。它将会变为数值零。他们几乎都不必转换为数值类型,他们如何进行转换的真正意义在于为了考虑一些偶然的结果,要转换一个字符串时,结果返回的是他们这些(或者是由于进行了一些数学计算操作才返回了这些)。

parseFloat

对于 parseFloat 解析空字符串将会返回对于 parseFloat 解析空字符串将会返回 NaN ,是因为空字符串不属于数字表达式。指数可以被解析,由0起头的八进制不会阻止字符串解析为十进制数。十六进制数却因为 "x" 无法作为数字被解析而停止解析而返回一个零。

非字符串类型转换成为快速转换,作为一个字符串传递给 parseFloat 。当那些类型转换作为字符串时不在是正常的结果,它的解析结果是 NaN,Objects 和 functions 。可能有自定义 toString 方法返回字符串将会被解析成为数值,这是一个特殊的要求。

parseInt
parseInt 函数的工作方式和parseFloat 有些相似,不同之处在于它是尝试把字符串转换为整型数值,只能辨认几个少数作为数字的符号。

parseInt 函数偶尔被用作转换单精度浮点数值类型为整型。由于这种转换首先要从字符串类型转换到单精度数值类型所以是不太适用的。另外由于它会产生一些错误,所以变得非常没有效率,比如 2e-200 这个科学计数法的数值正确的返回因该是零,但是 parseInt 返回 2。并且由于是Javascript 格式化,数值常常返回的是一些近似值。比如 1/2 + 1/3 + 1/6 = 0.9999999999999999 ,这个表达式的结果的近似值应该是 1 ,但 parseInt 竟会返回 0。
可以取得近似值的 Math.round,Math.ceil 和 Math.floor 都比较合适这个工作,为了取得结果,表达式将会被作为32位有符号整型,这个规则同样适用于下面这些情况。

注 Math.round 函数执行的是常见的四舍五入,0.4以及一下将会被忽略,0.5以及以上将会被加1。Math.ceil 函数在只要有小数的情况是就加1 。Math.floor 函数则无论小数大小都会被忽略。由这些函数的定义可知 parseInt 方法对于小数采取的是同 Math.floor 一样的处理方式。

ToInt32
ToInt32 是一个内置函数,虽然很有用,但是无法像 parseInt 一样被直接调用。用它转换Javascript变量到数值有一些不同寻常的方式。但是它能在一些有限的情况下被使用。位操作,比如按位OR(|)和 按位AND (&) 操作数值时,在使用它们操作时能被转换为数值类型。但是他们只工作在32位有符号的整形中,所以我们可以通过调用内置函数 ToInt32 返回已转换的32位有符号整形变量(进行类型转换)。结果就像是 parseInt 函数调用后,只是结果被限定为32位,因此都是数值,而没有 NaN 或者 Infinity。就算是用空值进行操作,结果返回的也是一个数值,使用一个位运算不会印象结果,却可以调用 ToInt32 函数。

甚至 undefined, objects 和 functions 都被转换为 0,布尔值 true 被转换成了数值 1。

 

 

posted @ 2010-10-23 13:32  GWPBrian  阅读(4706)  评论(0编辑  收藏  举报