犀牛书第三章主要讲了类型、值还有变量,本篇主要讲 数据类型。es6
须要注意引用类型和非引用类型的区别、-0、NaN、八进制、字符串编码等问题。编程
类型转换部分查看:数组
0.1 + 0.2 === 0.3;
复制代码
var e = '👋';
console.log(e.length);
复制代码
0 === -0;
1/0 === 1/-0;
复制代码
数据类型主要分为两类:浏览器
JavaScript 会在 程序期待使用对应数据类型 的地方 自动进行类型转换(常说的 隐式类型转换,如将非 Boolean 型的数据放在 if 判断条件中、使用非字符串和数字进行 + 运算等)。安全
JavaScript 变量是 无类型的,变量 能够赋予任何类型的值,而且 能够从新赋予不一样类型的值(也就是第一章所说的 弱类型 概念)。闭包
JavaScript 采用 词法做用域(也称 静态做用域,正是由于词法做用域的缘故,才会出现闭包,在变量定义的时候,它的做用域就已经肯定好了)。编程语言
JavaScript 中的数字采用 IEEE 754 标准,整数范围为 -(2**53) ~ 2**53
(Number.MAX_SAFE_INTEGER
的值为 2**53 - 1
,和这里相差了 1,由于 超出(安全)范围的值没法保证精度,故而最大值自己是不安全的,可能由某个失去精度的值转换而来️)。函数
下面是 MDN 中的例子。post
var x = Number.MAX_SAFE_INTEGER + 1;
var y = Number.MAX_SAFE_INTEGER + 2;
// 9007199254740991 9007199254740992 9007199254740992
console.log(Number.MAX_SAFE_INTEGER, x, y);
// true
console.log(x === y);
复制代码
JavaScript 中的实际操做如数组索引等 是基于 32 位整数 的。学习
// 4294967296
console.log(2**32);
// 安全
new Array(2**32 - 1);
// 报错:RangeError: Invalid array length
new Array(2**32);
复制代码
NaN 的意思是 Not a Number,不过 typeof NaN 是 number,因此它是一个不是(有效)数字的数字值。
因为 NaN 不等于任何值包括自身,可使用 a !== a 来判断 a 是否是一个 NaN 值。
八进制虽然大部分浏览器支持,可是它自己是 非标准的,在严格模式下 明令禁止(八进制使用 0 做为前置标识,这会在某些地方引发歧义)。
// 9
console.log(09);
// 15
console.log(017);
// 上述都是前导 0 可是却按照两种进制去进行了解析
(function() {
'use strict';
// 严格模式下会报错:SyntaxError: Octal literals are not allowed in strict mode.
console.log(09);
console.log(017);
})();
复制代码
JavaScript 中的浮点数计算精度问题是因为采用了 IEEE 754 浮点数表示法(大部分编程语言都是采用这个标准,因此这个问题真不是 JavaScript 的设计缺陷之类的),二进制表示法 致使十进制的小数没法精确的标识,因此致使一系列浮点计算的精度问题。
var a = 0.3 - 0.2;
var b = 0.2 - 0.1;
// false
console.log(a === b);
// 0.09999999999999998 0.1
console.log(a, b);
复制代码
这种时候建议使用整数来进行计算:
var a = (0.3 * 10 - 0.2 * 10) / 10;
var b = (0.2 * 10 - 0.1 * 10) / 10;
// true
console.log(a === b);
// 0.1 0.1
console.log(a, b);
复制代码
0 和 -0 并不彻底对等。
var a = 0, b = -0;
// 全等号会认为他们相等
console.log(a === b);
// 可是进行除法计算时将会影响计算结果
// Infinity -Infinity false
console.log(1/a, 1/b, 1/a === 1/b);
复制代码
JavaScript 字符串是由无符号的 16 位值 组成的序列,常见的 Unicode 字符都是经过 16 位内码表示的,若是出现 超出范围 的字符,将会遵循 UTF-16 编码规则,使用 两个 16 位值 标识,然而 JavaScript 中对字符串的操做都是 基于 16 位值。
// 👋 遵循 UTF-16 规则,实际编码为 '\ud83d\udc4b',在 JavaScript 中占用两个字符长度
var e = '👋';
// 2 d83d dc4b
console.log(e.length, e.charCodeAt(0).toString(16), e.charCodeAt(1).toString(16));
// true 👋 👋
console.log(e === '\ud83d\udc4b', e, '\ud83d\udc4b');
复制代码
从语义上,null 表明 空值,undefined 表明 未定义、不存在,正常而言 null 可用来给变量赋值(清空变量等),而 不多使用 undefined 去给变量赋值。
声明全局变量时变量会 成为全局对象的一个属性。
// 定义全局变量时 a 会直接挂载到 全局对象下
var a = {};
// {} {} true
console.log(a, window.a, a === window.a);
复制代码