skip to content
OnionTalk

重学前端学习笔记(1)--Js类型

winter老师的重学前端真的是一门很好的课程,看了第一课,收获颇多,填了很多Js类型的坑,总结如下。

基础类型

  1. Undefined
  2. Null
  3. Boolean
  4. String
  5. Number
  6. Symbol
  7. Object

boolean 这个类型比较简单,不单独作解释。Symbol 这个类型太复杂,后面单独总结。

Undefined 和 Null

  • undefined 并不是一个关键字。我们日常访问的 undefined 其实是访问的 global 级别的 undefined 变量,undefined 变量的值是基础类型 undefined。但是在现代浏览器中,undefined 都不能被覆写。
  • undefined 代表一个变量初始化了但是没有赋值,任何变量初始化前值都是 undefined。
  • null 是 JavaScript 的关键字,表示的是一个空值。
  • 所有变量定义都不要赋 undefined 值,这样会让代码难以理解(到底是代码没有赋值还是?)

String

  • string 的最大长度是 2^53-1,但是长度并不是指代字符数,而是字符串的 UTF16 编码的和,比如需要计算一个 emoji 的长度,你会发现是 2。
  • 字符串方法比如 length 和 charAt 都是基于字符串编码和的。
  • 字符串一旦构造便不可更改,属于值类型。

Number

  • Js 中除开规定有理数,还规定了 NaN,Infinity,-Infinity
  • Js 中有+0 和-0,在加减法中没有问题,在乘除法中,如果是 x * -0 会得到 -0,x/-0 会得到 -Infinity。
  • Js 中的 Number 类型范围是-2^53-2^53,如果不使用 BigInt,只能表示这个范围之内的整数
  • 非整数类型的 Number 无法使用 == 或者===来进行比较,0.2 + 0.1 == = 0.3 会返回 false,如果想要得到正确的匹配结果,请使用 Math.abs(0.1 + 0.2 -0.3) <= Number.EPSILON

Object

  • Js 中对象是属性的集合。属性分为数据属性和访问器属性,以 key-value 结构进行存储,key 可以是字符串或者是个 Symbol 类型。
  • Js 中的类和 Java 中的类有一些不同,Java 中的类代表的是真正的类型,但是 Js 中的类只是运行时对象的一个私有属性。
  • Number/String/Boolean 和 Symbol 这四个基本类型都自带对应的构造器,如果使用 new 操作符,会返回一个对象类型而不是基本类型。
  • Js 中的基本类型和对象的边界很模糊,可以直接在基础类型上调用方法,比如"abc".charAt(0),也可以通过给原型添加方法给基础类型增加方法。
  • 为什么基础类型可以调用对象方法?本质上是 . 运算符提供了装箱操作,这个运算符会根据基础类型构造一个临时对象。

类型转换

值转换表如下

StringToNumber

String 到 Number 的类型转换支持十进制/二进制/八进制和十六进制

  • 30
  • 0b111
  • 0o13
  • 0xFF

同时还支持科学计数法

  • 1e3
  • -1e-2

和 parseInt 和 parseFloat 相比,

  • 不传入第二个参数的情况下,parseInt 只支持 16 进制前缀,同时不支持科学计数法。在一些老浏览器中 parseInt 甚至会把 0 开头的字符串当做 8 进制进行转换。
  • parseFloat 只会把字符串当做十进制数进行转换。
  • 多数情况下,Number 比 parseInt 和 parseFloat 更优。

NumberToString

两种情况,当 number

  • 值较小时,采用十进制转换
  • 值较大时,采用科学计数法表示

装箱操作

把基本类型转换为对应的对象称作装箱操作

由于 Symbol 无法使用 new 操作符,如果想要声明一个 Symbol 对象,可以这么做。

var symbolObject = function () {
  return this;
}.call(Symbal('a'));

装箱对象有internal slot,这个 internal slot 是在 Object 被创建时动态生成的,并且生成后不可被改变。因此,可以使用如下代码获取数据的准确类型。

var symbolObject = Object(Symbol('a'));
Object.prototype.toString.call(symbolObject); // [object Symbol]

拆箱转换

在标准中定义了toPrimitive,这个操作能把对象类型转换到基本类型,这个操作即拆箱转换。

在拆箱转换中,会尝试调用 valueOf 和 toString 来获得基本类型,如果两个方法都不存在,或者没有返回基本类型,就会产生 TypeError。

需要注意的是,在对 String 类型进行拆箱时,会先调用 toString,其余情况会先调用 valueOf。

在 ES6 之后,允许显示指定 Symbol.toPrimitive 来覆盖默认的 toPrimitive 行为。该行为会覆盖默认的 toString 和 valueOf 判断。