数字
JavaScript中的非数字值有一点特殊:它和任何值都不想等,包括自身。也就是说,没有办法通过x==NaN来判断变量x是否是NaN。相反,应当使用x!=x来判断,当且仅当x为NaN的时候,表达式结果才为true。
函数isNaN()的作用与此类似,如果参数是Nan或者是一个非数字值,则返回true。JavaScript中有一个类似函数isFinite(),在参数不是NaN,INfinity或-Infinity的时候返回true。
负零值有些特殊,它和正零值是相等的。
0 == -0 //true
实数有无数个,但Javascript通过浮点数的形式只能表示其中有限的个数。Javascript采用了IEEE-745浮点数表示法(几乎所有现代编程语言所采用),这是一种二进制表示法,可以精确地二进制表示分数,但不能精确标示十进制分数,甚至0.1这样简单的数字。
0.3-0.2 == 0.2-0.1 //false
文本
JavaScript采用UTF-16编码的Unicode字符集,JavaScript字符串是由一组无符号的16位值组成的序列。最常用的Unicode字符都是通过16位的内码表示,并代表字符串中的单个字符,那些不能表示为16为的Unicode字符则则遵循UTF-16编码规则——用两个16位值组成的一个序列表示。这意味着一个Unicode字符可能长度为2:
var e = “e” //指数符号e,非字符e
e.length = 2;
null和undefined
null是JavaScript语言的关键字,它表示一个特殊值,常用来描述“空值”。对null执行typeof计算,结果返回字符串“object”,也就是说,可以将null认为是一个特殊的对象值,含义是“非对象”。但实际上,通常认为null是它自由类型的唯一一个成员,他可以表示数字、字符串和对象是“无值”的。
JavaScript还有第二个值来表示值的空缺。用未定义的值表示更深层次的“空值”。它是变量的一种取值,表明变量没有初始化,如果查询对象属性或数组元素的值时返回undefined,则说明这个属性或元素不存在。如果函数没有返回任何值,则返回undefined。
尽管null和undefined是不同的,但他们都表示“值的空缺”,两者往往可以互换。判断相等运算符“==”认为两者是相等的(要使用严格相等运算符“===”来区分它们)。在希望值时布尔类型的地方,它们都是false。
全局对象
全局对象的属性是全局定义的符号,JavaScript程序可以直接使用。
- 全局属性:undefined、Infinity和NaN
- 全局函数:isNaN()、parseInt()和eval()
- 构造函数:比如Date*(),RegExp(),String(),Object()和Array()
- 全局对象:Math和JSON
全局对象的初始属性不是保留字,但它们应该当作保留字来对待
包装对象
JavaScript对象是一种复合值:它是属性或已命名值的集合。通过“.”符号来引用属性值。当属性值是一个函数的时候,称为访问。通过o.m()来调用o中的m()方法。
var s = “hello worldl!”;
var word = s.substring(s.indexOf(” “) + 1, s.length);
字符串既然不是对象,为什么它会有属性呢?只要引用了字符串s的属性,JavaScript就会将字符串值通过new String(s)的方式转换为对象,这个对象继承了字符串的方法,并被用来处理属性的引用。一旦属性引用结束,这个新创建的对象就会销毁。
同字符串一样,数字和布尔值也具有各自的方法:通过Number()和Boolean()构造函数创建一个临时对象,这些方法的调用均是来自于这个临时对象。null和undefined没有包装对象:访问它们的属性会造成一个类型错误。
var s = “test”;
s.len = 4;
var t = s.len;
运行这段代码时,t的值时undefined。
第二行代码创建一个临时字符串对象,并给其len属性赋值为4,随即销毁这个对象。第三行通过原始的字符串值创建一个新字符串对象并尝试读取len属性,这个属性自然不存在。
存取字符串、数字或布尔值的属性时创建的临时对象称做包装对象,它只是偶尔用来区分字符串值和字符串对象、数字和数值对象以及布尔值和布尔对象。包装对象只是被看多一种实现细节,而不用特别关注。由于字符串、数字和布尔值的属性都是只读的,并且不能给他们定义新属性,所以它们是有别于对象的。
需要注意的是,可以通过String(),Number()或Boolean()构造函数来显示创建包装对象:
var s = “test”, n = 1, b = true;
var S = new String(s);
var N = new Number(n);
var B = new Boolean(b);
JavaScript会在表要时将包装对象转换为原始值,因为上段代码中的对象S、N和B常常——但不总是——表现的和值s、n和b一样。“==”等于运算符将原始值和其包装对象视为相等,但“===”全等运算符将它们视为不等。通过typeof运算符可以看到原始值和其包装对象的不同,s为string,S为Object。
值
Undifined null |
转换为字符串
“undefined” “null” |
数字
NaN 0 |
布尔值
False false |
对象
Throws TypeError Throws TypeError |
True false |
“true” “false” |
1 0 |
New Boolean(true) New Boolean(false) |
|
“”(空字符串)”1.2″(非空,数字)”one”(非空,非数字) |
0 1.2 NaN |
False True true |
New String(“”) New String(“1.2”) New String(“one”) |
|
0 -0 NaN Infinity -Infinity 1(无穷大,非零) |
“0” “0” “NaN” “Infinity” “-Infinity” “1” |
False False False True True ture |
New Number(0) New Number(-0) New Number(NaN) New Number(Infinity) New Number(-Infinity) New Number(1) |
|
{}(任意对象)[](任意数组)[9](一个数字元素)
[‘a’](其他数组) Function(){}(任意函数) |
“”
“9” 使用join()方法
|
0 9 NaN NaN |
True True True True true |
显式类型转换
尽管JavaScript可以自动做许多类型转换,但有时仍需要做显式转换,或者为了使代码变得清晰易读而做显示转换。
做显式类型转换最简单的方法就是使用Boolean(),Number(),String()或Object()函数。当不同new运算符调用这些函数时,它们会作为类型转换函数作类型转换:
Number(“3”) // =>3
String(false) //=>”false”或使用false.toString()
Boolean([]) //=>true
Object(3) //new Number(3)
需要注意的是,除了null或undefined之外的任何值都具有toString()方法,这个方法的执行结果通常和String()方法的返回结果一致。
Number类定义的toString()方法可以接收表示转换基数(radix)的可选参数,如果不指定此参数,转换规则将是基于十进制。同样,亦可以将数字转换为其他进制数(2~36)
Var n = 17;
Binaary_string = n.toSting(2); //10001
Octal_string = “0” + n.toString(8); //021
Hex_string = “0x” + n.toString(16); //Ox11
当处理财务或科学数据的时候,在做数字到字符串转换过程中,可以控制输出中小数点的位置和有效数字位数,或者决定是否需要指数计数法。Number类为这种数字到字符串的转换定义了三个方法。
- toFixed()根据小数点后的指定位数将数字转换为字符串,它从不使用指数计数法。
- toExponential()使用指数计数法将数字转换为指数形式的字符串,其中小数点只有一位,小数点后的位数则有参数指定(有效数字比指定的位数要多一位)
- toPrecision()根据指定的有效数字位数将数字转换为字符串,如果有效数子的位数少于数字整数部分的位数,则转换为指数形式。
如果通过Number()转换函数传入一个字符串,它会试图将其转换为一个整数或浮点数直接量,这个方法只能基于十进制进行转换,并且不能出现非法的尾随字符。parseInt()和pasreFloat()函数更加灵活。parseInt()可以接收第二个可选参数,这个参数指定数字转换的基数,合法的取值范围为2~36,如
parseInt(“11”,2);