这里整理一些 JavaScript 中类型的一些冷知识~
为什么有的编程规范要求用 void 0 代替 undefined?
这是因为 JavaScript 的一大设计失误 —— undefined 是变量而非关键字,所以它可以被篡改。不理解的话可以看下图:
undefined and void可以看到 undefined 被修改后返回了 4,明显被篡改了。
而表达式 void
没有返回值,因此返回结果是 undefined 。 void 并不改变表达式的结果,
只是让表达式不返回值。
所以,为了防止被篡改这种行为,有些规范要求使用 void 来替代返回 undefined 的行为。
字符串有最大长度吗?
字符串是有最大长度的,长度为 2^53 - 1 位。值得注意的是这里的长度是指 UTF16 编码字符(有些特殊字符串会占用两个字符,在 ES6 中添加了对这些特殊字符的处理方法)。
那些特殊的数字
Number 对象上的特殊数值
- Number.EPSILON 属性表示 1 与
Number
可表示的大于 1 的最小的浮点数之间的差值。 - Number.MAX_SAFE_INTEGER 常量表示在 JavaScript 中最大的安全整数(maxinum safe integer)(253 - 1)。
- Number.MAX_VALUE 属性表示在 JavaScript 里所能表示的最大数值。
- Number.MIN_SAFE_INTEGER 代表在 JavaScript中最小的安全的integer型数字 (-(253 - 1)).
- Number.MIN_VALUE 属性表示在 JavaScript 中所能表示的最小的正值。
- Number.NEGATIVE_INFINITY 属性表示负无穷大。
- Number.NaN 表示“非数字”(Not-A-Number)。和
NaN
相同。 - Number.POSITIVE_INFINITY 属性表示正无穷大。
Infinity 和 -Infinity
Infinity 表示无穷值,其实就是 Number.NEGATIVE_INFINITY。反正,负无穷大是 -Infinity,即 Number.NEGATIVE_INFINITY。
var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity
任何值除以 0 就等于(-)Infinity。
NaN
NaN 意指“不是一个数字”(not a number),但它却是数字类型。怎么样的代码会出现 NaN 呢?
var a = 2 / "foo"; // NaN
typeof a === "number"; // true
注意 NaN 是一个非自反的值,即自身不相等 。
NaN == NaN // false
为了解决检测 NaN 的问题,可以使用 ES6 提供的 Number.isNaN()
方法。
+0 和 -0
在 JavaScript 中存在 -0 这种表达方式:
var a = -1 * 0 // -0
var b = 1 * 0 // 0
要注意将值为 -0 的变量转换为字符串后结果为 "0"
。
-0 可以用来做数字符号位、行为移动方向等方面起到一定的作用。
为什么在 JavaScript 里 0.1 + 0.2 不等于 0.3?
0.1 + 0.2 == 0.3 // false
因为 JavaScript 中使用的是二进制浮点数,二进制浮点数中的 0.1 和 0.2 并不是十分精确,它们相加的结果并非刚好等于
0.3 ,而是一个比较接近的数字 0.30000000000000004 ,所以条件判断结果为 false 。
消除误差的方式如下:
var n1 = 0.1 + 0.2
var n2 = 0.3
Math.abs( n1 - n2 ) < Number.EPSILON; // true
上文中我们提到了 Number.EPSILON 表示 1 与Number
可表示的大于 1 的最小的浮点数之间的差值
。所以只要两个值相减的绝对值结果小于差值就算相等。
什么是基本类型的装箱和拆箱?
装箱
基本类型的装箱我在之前已经提起过了,其实就是在基本类型使用一些方法时会使用相应的装箱对象的 prototype 中的方法。具体来说就是 JavaScript 会零时为变量包装一个装箱对象。
var a = "abc";
a.length; // 3
a.toUpperCase(); // "ABC"
当字符串 a 使用属性和方法时,JavaScript 零时创建了一个 new String('123')
对象并调用这个对象上的属性和方法。
注意:基本类型变量会在调用属性和方法时会零时创建装箱对象,这些变量还是基本类型的。而创建装箱对象创建的则是一个对象。
基本类型和装箱对象拆箱
既然基本类型能够自动装箱成为装箱对象,那么装箱对象如何转为基本类型呢?
简单!使用 valueOf() 方法:
var a = new String( "abc" );
var b = new Number( 42 );
var c = new Boolean( true );
a.valueOf(); // "abc"
b.valueOf(); // 42
c.valueOf(); // tru
其实还可以使用强制类型转换的方式进行拆箱。
强制类型转换都哪些?
这里贴一张 JavaScript 中强制类型转换的关系图,讲的很详细:
类型转换关系图下面归纳几点类型转换的知识点:
- JSON.stringify() 方法在强制转换成字符串的时候很好用。
- 强制类型转换成 number 类型的时候要注意进制问题。
- 直接使用装箱函数 String、Number 和 Boolean 可以进行强制类型转换,这种转换方式也被叫做显式类型转换。
- 使用字符串拼接的方式可以强制类型转换为字符串,这种转换方式也被叫做隐式类型转换。
- 使用
!!value
可以强制类型转换为布尔类型。 - parseInt、parseFloat 方法可以将 string 转换为 number 类型。
参考资料
- 极客时间专栏 —— 《重学前端》
- 《你不知道的 JavaScript (中)》
最后
这些冷知识虽然用的不多,但是也能帮我们更好的理解和使用 JavaScript 类型相关的知识~
网友评论