与众不同的数据类型


在 JavaScript 中,有基本(Primitive)数据类型、复合(Composite)数据类型,还有两个特殊的值nullundefined

基本数据类型包括了数值、字符串与布尔值,类型名称分别为numberstring与布尔值boolean

在 JavaScript 中,没有整数与浮点数的区别,数值都是 〈IEEE 754 标准 64 位浮点数,可表示的数字最小值为Number.MIN_VALUE(5e- 324),而最大值为Number.MAX_VALUE(1.7976931348623157e+308)。根 据 〈ECMA Section 8.5 - The Number Type〉,可表达的整数为 -253到 253之间,不包含-253与 253,例如,253,也就是 9007199254740992 不安全,因为你写下 9007199254740993,结果还是代表着 9007199254740992:

> 9007199254740993
9007199254740992
>

注意位运算符的结果会是 32 位有符号整数,像是~>>等。

与其他程序语言相同,编写数值时要使用数值字面量(Number literal),默认是十进制整数,也可以用 0 开头表示八进制整数,或是用 0x 开头表示十六进制整数。例如:

10(十进制)
0xFF(十六进制)

若要表示浮点数,则可使用科学计数表示。例如:

3.14
5.231E13(5.231 * 10^13)
1.31E-32(1.31 * 10^-32)

数值有几个特殊值,例如+Infinity(或简单写为Infinity)表示 正无限大,-Infinity表示负无限大。也可以使用Number.POSITIVE_INFINITY获取正无限大,Number.NEGATIVE_INFINITY获取负无限大。另外还有NaNNumber.NaN表非数值(Not a Number),例如你尝试作1 / 'two'时,就会出现NaN的结果。

注意,NaN不等于任何值,NaN也不等于NaN, 如果你要测试某值结果是否为NaN,方法之一可以用isNaN函数来测试。例如:

> NaN === NaN;
false
> isNaN(NaN);
true
> isNaN(1 / 'two');
true
>

不过,isNaN不可靠,如果传入的数值是NaN确实会是true, 然而,无法转换至数字的值,具体来说,也就是丢给Number()会返回NaN的值,都会让isNaN的结果为true,像是非数字格式且非空的字符串、undefined等。例如:

> isNaN('caterpillar');
true
> isNaN(undefined);
true
> isNaN('0');
false
>

如果想测试某值是不是NaN,最好自行编写,还好,因为NaN是 JavaScript 中唯一自身不等于自身的值,所以可以自己定义一个isRealNaN函数:

function isRealNaN(value) {
    return value !== value;
}

console.log(isRealNaN(NaN));           // true
console.log(isRealNaN('caterpillar')); // false
console.log(isRealNaN(undefined));     // false

问题并不会这么结束,虽然NaN代表「Not a Number」,不过,typeof NaN的结果却是'number',这实在很囧:

> typeof NaN;
'number'
>

当然,在 JavaScript 中,typeof本身就有些问题,不过,如果你想要检查值是不是一个有限数字,可以借助isFinite函数,它对NaNInfinity测试的结果会是false,不过,isFinite同样会将指定的值丢给Number(),用它的返回值做检查,因此,isFinite('15')的结果会是true

如果你真的只想检查一个number是否为有限数字,可以自己定义一个isRealFiniteNumber函数:

function isRealFiniteNumber(value) {
    return typeof value === 'number' && isFinite(value);
}

console.log(isRealFiniteNumber(NaN));       // false
console.log(isRealFiniteNumber(Infinity));  // false
console.log(isRealFiniteNumber('93'));      // false
console.log(isRealFiniteNumber(93));        // true

在 JavaScript 中,字符串是基本数据类型,可使用单引号或双引号来包括一串文本,用以表示字符串。例如:

var str1 = 'text1';
var str2 = "text2";

JavaScript 中没有字符类型,以单引号或双引号来包括单一字符,都是字符串类型。例如:

> typeof 'A';
'string'
> typeof "B";
'string'
>

typeof可以用来测试某数据的类型,会返回类型的字符串描述,例如,对数值使用typeof会返回'number'。对字符串使用则返回是'string'。在编写字符串字面量 (String literal)时可使用单引号或双引号,一般习惯在 JavaScript 程序中采用单引号,而将双引号保留给 HTML 使用,避免跳脱文本的麻烦。例如:

var html = '<input type="text" value="defalut">';

你可以使用\uxxxx,指定 Unicode 码来表示字符串,例如:

> '\u0048\u0065\u006C\u006C\u006F'
'Hello'
> '\uF9F4'
'林'
> '\u54C8\u56C9'
'哈啰'
>

如果字符串中的字符不有 0000 ~ FFFF 的范围之中(也就是 BMP 外的字符),例如高 音谱记号的 1D11E,那么要分别以高低字节来表示,也就是'\uD834\uDD1E'

布尔值只有两个值,truefalse,分别表示真与假,对布尔值使用typeof, 结果会是'boolean'

复合数据类型就是指对象(object),基本上它们都是Object的实例,使用typeof测试复合数据类型的结果就是'object'。例如:

> typeof new Object();
'object'
> typeof {};
'object'
> typeof [];
'object'
>

[]创建一个数组,也就是一个Array实例,它当然是一个对象,因此typeof []的结果就是'object'

null是 JavaScript 中特殊的值,表示没有任何东西。应用的时 机就是在变量不参考至任何对象时,可以指定变量为null,或测试变量是否参考至null

> var x = null;
undefined
> x === null;
true
>

如果你想知道某个对象是哪个类型的实例,可以使用instanceof来测试。例如:

> var x1 = {};
undefined
> var x2 = [];
undefined
> x1 instanceof Object;
true
> x2 instanceof Object;
true
> x1 instanceof Array;
false
> x2 instanceof Array;
true
>

null使用typeof的结果会是'object', 这很怪(只能强记),因为用instanceof测试null是否为Object的实例,结果却是false

> typeof null;
'object'
> null instanceof Object;
false
>

注意!以下的x值有参考至一个值,那就是null,而不是undefined

var x = null;

以下的x才是undefined

var x;

undefined是 JavaScript 中特殊的值,当你试图获取某个 没指定任何值的变量(也没指定null)或特性(Properties)时,就会出现undefined的结果。对undefined使用typeof的结果是'undefined'。 在 Node.js 中,undefined会显示 undefined。

注意,别与直译错误时出现的「未定义」消息搞错了,例如,以下的示范中,并没有事先定义x,因此x未定义,会发生ReferenceError的错误:

> var y = x;
ReferenceError: x is not defined
    at repl:1:9
    at REPLServer.self.eval (repl.js:110:21)
    at repl.js:249:20
    at REPLServer.self.eval (repl.js:122:7)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)
>

如果是以下的程序,是可以正确执行的代码,xy的结果都是undefined

> var x;
undefined
> var y = x;
undefined
> x
undefined
> y
undefined
>

undefined本身等于undefined

> undefined === undefined;
true
>




展开阅读全文