JavaScript学习笔记11-值

  |  

前言

了解和合理运用JavaScript的内置值类型


59



数组

与其它强类型语言不同,在JavaScript中,数组可以容纳任何类型的值。对数组声明后即可向其中加入值,不需要预设定大小。

使用delete可以将单元从数组中删除,但是单元删除后,数组的length属性并不会发生改变。

数组通过数字进行索引,但是在JS中,数组也是对象,所以也可以包含字符串键值和属性,但是这些并不计算在数组长度中。同时,如果字符串的键值能够强制类型转换为十进制数字的话,它就会被当作数字索引来使用

1
var a = []; a['13'] = 1; a.length; // 14

类数组的转换

1
Array.prototype.slice.call(arguments)l;

字符串

字符串与数组很相似,都有length属性以及indexOf()和concat()方法

JavaScript中字符串是不可变的,而数组是可变的。字符串的不可变指的是字符串的成员方法并不会改变字符串的原始值,而是创建并返回一个新的字符串。

由于字符串和数组的相似性,所以使用许多数组函数来处理字符串很方便,虽然字符串中并没有这些函数,但是可以通过借用数组的非变更方法来处理字符串

1
2
3
4
5
6
7
var a = 'foo';
var b = Array.prototype.join.call(a, '.');
var c = Array.prototype.map.call(a, function(v) {
return v.toUpperCase() + '.';
}).join('');
console.log(b); //f.o.o
console.log(c); //F.O.O

另一个不同的点在于字符串的反转。数组有要给字符串无法借用的可变更成员函数reverse();

1
2
var b = ['f', 'o', 'o'];
b.reverse(); // ['o', 'o', 'f'];

不过存在变通的方法,就是先将字符串转换为数组,处理完以后再将结果转换回字符串

1
var c = a.split('').reverse().join('');

需要注意的是,上述的所有方法对于包含复杂字符(Unicode,如星号、多字节字符)的字符串时并不适用,这些复杂字符需要额外的工具库来处理。

数字

JavaScript只有一种数值类型:number,包括“整数”和带小数的十进制数。整数之所以带上引号,是因为JavaScript没有真正意义上的整数。JavaScript中的整数就是没有小数的十进制数。

数字的语法

数字前的0和小数点后小数部分最后的0可以省略

1
2
3
4
var a = 0.42;
var b = .42;
var c = 42.0
var b = 42.

特别大和特别小的数字使用指数格式显示,与toExponential()函数输出的结果相同

1
2
3
var  a = 5E10;
a; // 50000000000
a.toExponential(); // "5e+10"

由于数字值可以使用Number对象进行封装,所以数字值可以调用Number.prototype中的方法。

toFixed方法指定小数部分的显示位数

1
2
var a = 42.59;
a.toFixed(4); // 42.5900

toPrecision()方法来指定有效数位的显示位数

1
a.toPrecision(1); //"4e+1"

这些方法不仅适用于数字变量,也适用于数字常量。不过对于.运算符需要给予特别的关注,因为它是一个有效的数字字符,会被优先识别为数字常量的一部分,然后才是对象属性访问运算符

1
2
3
42.toFixed(3); // SyntaxError
(42).toFixed(3); // 42.000
42..toFixed(3)

数字常量还可以用其它格式来表示

1
2
0xF3,0XF3; // 十六进制
0o363, 0O363; // 八进制

较小的数值

JavaScript遵循IEEE 754规范,使用二进制浮点数。这也导致了下列的情况

1
0.1 + 0.2 === 0.3 // false

这个等式在数学上是严格成立的,但是由于二进制浮点数中0.1和0.2并不十分精确,它们相加的结果并非刚好等于0.3,而是一个比较接近的数字 0.30000000000000004,所以条件判断结果为 false。

那么我们怎样使他们成立呢。最常见的方法就是设置一个误差范围,通常称为”机器精度”,对于JavaScript来说这个值通常是2^-52。

从ES6开始,该值直接定义在了Number.EPSILON中,我们可以直接拿来使用,也可以为ES6之前的版本增加

1
2
3
if(!Number.EPSILON) {
Number.EPSILON = Math.pow(2, -52);
}

这样我们就可以使用Number.EPSILON来比较两个数字是否相等

1
2
3
4
5
6
7
function numbersCloseEnoughToEqual(n1,n2) {
return Math.abs( n1 - n2 ) < Number.EPSILON;
}
var a = 0.1 + 0.2;
var b = 0.3;
numbersCloseEnoughToEqual( a, b ); // true
numbersCloseEnoughToEqual( 0.0000001, 0.0000002 ); // false

JavaScript能呈现的最大的浮点数是1.798e+308,它定义在Number.MAX_VALUE中。最小的浮点数是5e-324,定义在Number.MIN_VALUE中。

整数的安全范围

JavaScript的数字呈现方式决定了整数的范围远小于Number.MAX_VALUE。

能被安全的呈现的最大整数是2^53-1,在ES6中定义为Number.MAX_SAFE_INTEGER。最小的整数是-(2^53-1),在ES6中定义为Number.MIN_SAFE_INTEGER.

在JavaScript中如果要处理一些比较大的数字,比如数据库中的64位ID,就需要将其转换为字符串来处理

整数检测

要检测一个整数,可以使用ES6中的Number.isInteger()方法

1
2
Number.isInteger(42.000); // true
Number.isInteger(42.3); // false

也可以为ES6之前的版本polyfill Number.isInteger()方法

1
2
3
4
5
if(!Number.isInteger) {
Number.isInteger = function(num) {
return typeof num == 'number' && num % 1 == 0;
}
}

要检测一个值是否是安全的整数,可以使用ES6中的Number.isSafeInteger()方法

1
2
Number.isSafeInteger(Math.pow(2, 53)); // false
Number.isSafeInteger(Math.pow(2, 53) - 1); // true

32位有符号整数

虽然整数最大能够到达53位,但是有些数字操作(例如位操作)只适用于32位数字,所以这些操作中数的安全范围就要小很多了。

可以使用a | 0将变量a中的数值转换为32位有符号整数,因为数位运算符符|只适用于32位整数,其它数位会被忽略。

特殊数值

不是值的值

undefined 类型只有一个值,即 undefined。null 类型也只有一个值,即 null。它们的名
称既是类型也是值。
undefined 和 null 常被用来表示“空的”值或“不是值”的值。二者之间有一些细微的差
别。例如:

  • null 指空值(empty value)
  • undefined 指没有值(missing value

或者:

  • undefined 指从未赋值
  • null 指曾赋过值,但是目前没有值

null 是一个特殊关键字,不是标识符,我们不能将其当作变量来使用和赋值。

然而undefined 却是一个标识符,可以被当作变量来使用和赋值。

undefined是一个内置标识符,可以通过void运算符来获得该值。void并不改变表达式的结果,只是让表达式不返回值:

1
2
var a = 42;
console.log(void a, a); // undefined 42

特殊的数字

不是数的数

NaN意指不是一个数字,或者说表示执行数学运算没有成功,这是失败后返回的结果

1
2
let a = 2 / 'foo'; // NaN
typeof a === 'number'; // true

且NaN它和自身不等,是唯一一个非自反的值

所以我们只能使用isNaN来判断一个值是否为NaN,但是这个函数有一个缺陷,就是它只检查参数是否不是NaN,也不是数字

1
2
3
4
let a = 2 / 'foo',
b = 'foo';
window.isNaN(a); // true
window.isNaN(b); // true

从ES6开始,我们使用Number.isNaN来判断。或者用一个更简单的办法,及利用NaN不等于自身的办法

1
a !== a

无穷数

在JavaScript,以下运算是被允许的

1
let a = 1/0;

他的结果是Infinity(即Number.POSITIVE_INFINITY),就是无穷。同理还有-Infinity

一旦JavaScript的运算结果溢出,此时结果为Infinity或者-Infinity。

而且一旦溢出为无穷数,就再也无法得到有穷数了。

而当无穷除以无穷,那么他得到的结果是NaN

零值
JavaScript有一个常规的0(也叫做+0)和一个-0。

-0除了可以用作常量外还可以是某些数学运算的返回值

1
2
let a = 0 / -3; // -0
let b = 0 * -3; // -0

但是对-0进行字符串化会返回”0”。不过将字符串转换为数字,-0还是-0

而且更特殊的一点是

1
0 === -0 // true

所以我们需要特殊的方式来判断-0

1
2
3
4
function isNegZero(n) {
n = Number( n );
return (n === 0) && (1 / n === -Infinity);
}
文章目录
  1. 1. 数组
  2. 2. 字符串
  3. 3. 数字
    1. 3.1. 数字的语法
    2. 3.2. 较小的数值
    3. 3.3. 整数的安全范围
    4. 3.4. 整数检测
    5. 3.5. 32位有符号整数
  4. 4. 特殊数值
    1. 4.1. 不是值的值
    2. 4.2. 特殊的数字