1. toPrimitive
toPrimitive抽象操作用于将一个值转为原始值.这个操作没有对应的JavaScript API,但是它在Object类型的值进行toString和toNumber操作时被使用.toPrimitive操作接收2个参数,一个时要转换的值value,一个是偏好类型preferedType,取值有3种情况:default number string
具体转换规则如下面的代码所示:
// https://tc39.es/ecma262/#sec-ordinarytoprimitivefunction ordinaryToPrimitive(value, hint) {const methodNames = hint === 'number' ? ['valueOf', 'toString'] : [['toString', 'valueOf']];for (const methodName of methodNames) {const result = value[methodName]?.();if (Object(result) !== result) return result;}throw new TypeError('can not transform');}// https://tc39.es/ecma262/#sec-toprimitivefunction toPrimivite(value, preferedType) {// 如果是原始值则不需要进行转换,直接返回if (Object(value) !== value) return value;if (value[Symbol.toPrimitive]) {const result = value[Symbol.toPrimitive](preferedType ?? 'default');if (Object(result) !== value) return result;throw new TypeError('can not transform');}return ordinaryToPrimitive(value, preferedType ?? 'number');}
对于 valueOf 和 toString 方法,它的调用结果需要具体对待。
valueOf 方法首先存在于 Object 的原型上,Object.prototype.valueOf 返回调用对象本身。原始值包装类型:Boolean,Number,String 重写了该方法,Wrapper.prototype.valueOf 返回包装对象的对应原始值。而对于 Date 实例而言,valueOf 方法返回一个整数,表示从 1970 年 1 月 1 日至今所经过的毫秒数。
toString 方法首先存在于 Object 的原型上,Object.prototype.toString 返回形如 [object tag] 的字符串。不过原始值包装类型:Boolean, Number, String 方法重写了该方法,Wrapper.prototype.toString 返回包装对象的对应原始值的字符串表示。Array 也重写了该方法,Array.prototype.toString 效果上等于 Array.prototype.join。Date 也重写了该方法,返回当前日期的表示。
2.toBoolean
toBoolean 操作是一个抽象的操作,它对应 JavaScript 中的 Boolean(value) 类型转换函数(或者 !! 操作符)。这个操作将一个任意值转换为 1 个 Boolean 类型的值(true 或 false 值)。
| 值的类型 | true | false |
|---|---|---|
| Undefined 和 Null | 无 | undefined, null |
| Boolean | true | false |
| Number | 非 0, -0, NaN 的 Number 值 | 0, -0, NaN |
| BigInt | 非 0n, -0n | 0n, -0n |
| String | 非 ‘’ | ‘’ |
| Symbol | 无 | 全部值 |
| Object | 全部值 | 无 |
如下面的代码所示:
const { log } = console;const results = [undefined, null, false, 0, NaN, Infinity, -12n, '', Symbol('symbol'), {}].map(Boolean,);log(...results);// -> false false false false false true true false true true
3.toString
toString 抽象操作对应 JavaScript 的 String(value) 类型转换函数。它将一个任意值转换为一个 String 类型的值。
- 原始类型
Undefined,Null,boolean,Number,BigInt,String,Symbol 这些原始类型会被转为对应的字符串表示,如下面的代码所示:
const { log } = console;const results = [undefined, null, false, 0, NaN, Infinity, -12n, 'text', Symbol('symbol')].map(String,);log(...results);// -> 'undefined' 'null' 'false' '0' 'NaN' 'Infinity' '-12' 'text' 'Symbol(symbol)'
- Object 类型
对于 Object 类型,String() 函数转换规则如下:
4.toNumber
toNumber 抽象操作用于将一个值转换为 Number 类型,它在 JavaScript 中的对应 API 是 Number() 类型转换函数。
toNumber 转换规则如下表所示:
| 值的类型 | 转换结果 |
|---|---|
| Undefined | NaN |
| Null | 0 |
| Boolean | true => 1, false => 0 |
| Number | 直接返回 |
| BigInt | 报错 |
| String | 数值型字符串到数值,否则为 NaN |
| Symbol | 报错 |
| Object | toNumber(toPrimitive(value, ‘number’)) |
上表值得说明的是,String 类型在转换时,字符串必须满足数值型字符串。否则转换结果就是 NaN。而 Object 类型的值在进行转换时,首先经过 toPrimitive 抽象操作转换为原始值,然后再根据上表进行转换。
