数值类型 Number
JavaScript 只有一种数字类型,它在内部被表示为 64 位的浮点数,和 Java 的 double 数字类型一样。
与其他大多数编程语言不同的是,它没有分离出整数类型,所以 1 和 1.0 的值相同,这提供了很大的方便,避免了一大堆因数字类型导致的错误。数值类型 Number 是 JS 中的原始数据类型,同时 JS 也支持 Number 对象(一个原始数值的包装对象)。在需要时,JS 会自动在原始形式和对象形式之间转换。
定义方式
JavaScript 采用 IEEE754 格式来表示数字,不区分整数和浮点数,JS 中的所有数字都用浮点数值表示。
由于浮点型数值需要的内存空间是保存整数值的两倍,因此,JS 会不失时机地将浮点数值转换成整数值,若小数点后没有跟任何数字或者浮点值本身表示的就是一个整数,这个数值会作为整数值来保存。
console.log(1.0,1.0===1); // 1 true console.log(1.,1.===1); // 1 true
当一个数字直接出现在 JS 中时,称为数值直接量/字面量;使用 new 操作符用做构造函数时,称为 Number 对象。
[ 整数 ] JS 整数表示共有四种字面量格式:十进制、二进制、八进制、十六进制。
但,在进行算术计算时,所有以二进制、八进制和十六进制表示的数值最终都将被转换成十进制数值。
- 八进制字面值的第一位必须是 0,然后是八进制数字序列(0-7)。如果字面值中的数值超出了范围,那么前导 0 将被忽略,后面的数值被当作十进制数解析。由于某些 JS 的实现不支持八进制字面量,且八进制字面量在严格模式下是无效的,会导致 JS 抛出错误。所以,尽量不使用八进制字面量。
- 十六进制字面值的前两位必须是0x,后跟十六进制数字序列(0-9,a-f),字母可大写可小写。如果十六进制中字面值中的数值超出范围,如出现 g、h 等会报错。
- 二进制字面值的前两位必须是 0b,如果出现除 0、1 以外的数字会报错。
var num2 = 0b101; console.log(num2); // 5 var num2 = 0b2; console.log(num2); // 报错 var num8 = 012; console.log(num8); // 10 var num8 = 09; console.log(num8); // 9 var num16 = 0x11; console.log(num16); // 17 var num16 = 0xg; console.log(num16); // 报错
[ 浮点数 ] 数值中必须包含一个小数点,且小数点后面必须至少有一位数字。
// 与整数支持多进制不同,一般地,浮点数只可用十进制表示。 var num1 = 011.1; // 报错 var num2 = 0x11.1; // 报错 var num3 = 011e1; // 报错 var num4 = 0x11e1; // 出错,会被识别成整数,结果为4577 // 虽然小数点前面可以没有整数,但不推荐。 var num1 = 1.1; var num2 = 1.; var num3 = .1; console.log(num1,num2,num3); // 1.1,1,0.1 // 由于JavaScript采用IEEE754格式表示数字,浮点数不是精确值,所以涉及浮点数的比较和运算时要特别小心。 console.log(0.1 + 0.2 === 0.3); // false console.log(0.3 / 0.1); // 2.9999999999999996 console.log((0.3 - 0.2) === (0.2 - 0.1)); // false
[ 科学计数法 ] 对于极大或者极小的数,可以用科学计数法 e 来表示的浮点数值来表示。科学计数法允许字母 e 或 E 的后面,跟着一个整数,表示这个数值的指数部分。以下两种情况,JavaScript 会自动将数值转为科学计数法表示:
- 小于 1 且小数点后面带有 6 个 0 以上的浮点数值
0.0000003 // 3e-7 0.000003 // 0.000003
- 整数位数字多于 21 位
1234567890123456789012 // 1.2345678901234568e+21 1234567890123456789012.1 // 1.2345678901234568e+21 123456789012345678901 // 123456789012345680000
[ 特殊值 ] 最值、无穷大、非数字、正负零
[1] 最值
Number.MAX_VALUE 代表 JavaScript 最大值,Number.MIN_VALUE 代表 JavaScript 最小正值。
console.log(Number.MIN_VALUE,Number.MAX_VALUE) // 5e-324,1.7976931348623157e+308 // 安全整数 Number.MAX_SAFE_INTEGER表示最大整数(2的53次幂-1),Number.MIN_SAFE_INTEGER表示最小整数-(2的53次幂-1)。 // 9007199254740991 true console.log(Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER===Math.pow(2, 53)-1) // -9007199254740991 true console.log(Number.MIN_SAFE_INTEGER,Number.MIN_SAFE_INTEGER===-(Math.pow(2, 53)-1))
[2] 无穷大 Infinity
Infinity 是一个全局属性,用来存放表示无穷大的特殊数值。实际上,Number.POSITIVE_INFINITY 对应的是Infinity,代表正无穷;而 Number.NEGATIVE_INFINITY 对应的是 -Infinity,代表负无穷。
consolec .log(Number.POSITIVE_INFINITY,Number.NEGATIVE_INFINITY);//Infinity -Infinity
- 用 for/in 循环不可枚举 Infinity 属性,用 delete 操作符也无法删除它。
- Infinity 有正负之分。
Math.pow(2,Math.pow(2,100)); //Infinity 1/0; //Infinity -0/0; //-Infinity Infinity === -Infinity; //false
- Infinity 参与的运算结果只能是其本身、0 或 NaN。
2 * Infinity; // Infinity 2 - Infinity; // -Infinity 2 + Infinity; // Infinity 2 / Infinity; // 0 Infinity / 2; // Infinity Infinity * Infinity; // Infinity Infinity - Infinity; // NaN Infinity + Infinity; // Infinity Infinity / Infinity; // NaN
- 可以通过 isFinite() 来确定一个数值是不是有穷的,包含着隐式类型转换 Number()。如果是 +-Infinity 或 NaN时,返回 false,否则为 true。
console.log(isFinite(Infinity)) // false console.log(isFinite(NaN)) // false console.log(isFinite(Number.MAX_VALUE)) // true console.log(isFinite(true)) // true
[3] 非数字 NaN // not a number
NaN 表示非数字,NaN 与任何值都不相等,包括 NaN 本身,且任何涉及 NaN 的操作都会返回 NaN。
5 - 'x'; // NaN Math.acos(2); // NaN 0 / 0; // NaN NaN == NaN; // false NaN == Infinity; // false [NaN].indexOf(NaN); // -1 Boolean(NaN); // false
- isNaN() 来判断这个数字是不是 NaN,包含着隐式类型转换 Number();
console.log(isNaN(Infinity));//false console.log(isNaN(0));//false console.log(isNaN(NaN));//true console.log(isNaN('Hello'));//true
- 判断 NaN 更可靠的方法是,利用 NaN 是 JavaScript 之中唯一不等于自身的值这个特点,进行判断。
function myIsNaN(value) { return value !== value; }
[4] 正负零
在 JS 内部,实际上存在 2 个 0 :一个是 +0,一个是 -0。它们是等价的。
-0 === +0; // true 0 === -0; // true 0 === +0; // true一般地,+0 和 -0 都会被当做 0 来看待,但是 +0 或 -0 当作分母,返回的值是不相等的。
console.log(1/+0); // Infinity console.log(1/-0); // -Infinity console.log((1/+0) === (1/-0)); // false
实例方法
关于 Number() 对象的实例方法总共有 6 个,分为两类:
[1] 对象通用方法:toString()、toLocalString()、valueOf()
- valueOf() 方法返回对象的数字字面量
- toString() 方法将数字转换为字符串
- toLocalString() 方法将数字转换为本地惯例格式化数字的字符串
console.log(typeof 1.1.valueOf(),1.1.valueOf()); // number 1.1 console.log(typeof 1.1.toString(),1.1.toString()); // String '1.1' console.log(typeof 1.1.toLocaleString(),1.1.toLocaleString()); // String '1.1' [注意]如果数字不加括号,点会被javascript引擎解释成小数点,从而报错 console.log(typeof 1.valueOf(),1.valueOf()); // 报错 console.log(typeof 1.toString(),1.toString()); // 报错 console.log(typeof 1.toLocaleString(),1.toLocaleString()); // 报错 console.log(typeof (1).valueOf(),(1).valueOf()); // number 1 console.log(typeof (1).toString(),(1).toString()); // String '1' console.log(typeof (1).toLocaleString(),(1).toLocaleString()); // String '1' 除了为数字加上括号,还可以在数字后面加两个点,javascript会把第一个点理解成小数点,把第二个点理解成调用对象属性,从而得到正确结果。 console.log(10..toString()); // "10" console.log(10 .toString()); // "10" console.log(10.0.toString()); // "10" toString()方法可以接受一个参数,该参数应当是2到36之间的整数,表示输出的进制。如果该参数不存在,或者为undefined,默认将数值先转为十进制,再输出字符串。 var num = 10; console.log(num.toString()); // '10' console.log(num.toString(2)); // '1010' console.log(num.toString(8)); // '12' console.log(num.toString(10)); // '10' console.log(num.toString(16)); // 'a' console.log(num.toString(undefined)); // '10' 如果参数超出2-36的范围,或者为其他值时,报错 console.log((10).toString(0)); // 报错 console.log((10).toString(null)); // 报错
[2] 改变数值显示形式并转换为字符串的方法:toFixed()、toExponential()、toPrecision()
- toFixed():按照指定的小数位返回数值四舍五入后的字符串表示( 常用于处理货币值 )。
// toFixed()里的参数只接受0-20,若不传参或参数为undefined,则相当于参数是0。 var num = 10.456; console.log(num.toFixed(2)); // '10.46' console.log(num.toFixed()); // '10' console.log(num.toFixed(0)); // '10' console.log(num.toFixed(undefined)); // '10' console.log(num.toFixed(-1)); // 报错
- toExponential():返回数值四舍五入后的指数表示法( e 表示法 )的字符串表示,参数表示转换后的小数位数。
// toExponential()方法里的参数只接受0-20, // 但与toFxied()不同的是,若不传参或参数为undefined,则保留尽可能多的有效数字;若参数是0表示没有小数部分。 var num = 10.456; console.log(num.toExponential(2)); // '1.05e+1' console.log(num.toExponential()); // '1.0456e+1' console.log(num.toExponential(0)); // '1e+1' console.log(num.toExponential(undefined)); // '1.0456e+1' console.log(num.toExponential(-1)); // 报错
- toPrecision():接收一个参数,即表示数值所有数字的位数(不包括指数部分),自动调用 toFixed() 或 toExponential()
// toPrecision()里的参数只接受1-21,若不传参或参数为undefined则相当于调用toString()方法。 var num = 10.1; console.log(num.toPrecision(3)); // '10.1' console.log(num.toPrecision(2)); // '10' console.log(num.toPrecision(1)); // '1e+1' console.log(num.toPrecision()); // '10.1' console.log(num.toPrecision(undefined)); // '10.1' console.log(num.toPrecision(0)); // 报错
[ 注意 ] toFixed()、toExponential()、toPrecision() 在小数位用于四舍五入时都不太可靠,跟浮点数不是精确储存有关。
console.log((12.25).toPrecision(3)); // "12.3" console.log((12.25).toFixed(1)); // "12.3" console.log((12.25).toExponential(2)); // "1.23e+1" console.log((12.35).toPrecision(3)); // "12.3" console.log((12.35).toFixed(1)); // "12.3" console.log((12.35).toExponential(2)); // "1.23e+1"