1. toPrimitive
toPrimitive
抽象操作用于将一个值转为原始值.这个操作没有对应的JavaScript API,但是它在Object
类型的值进行toString
和toNumber
操作时被使用.toPrimitive
操作接收2个参数,一个时要转换的值value
,一个是偏好类型preferedType
,取值有3种情况:default number string
具体转换规则如下面的代码所示:
// https://tc39.es/ecma262/#sec-ordinarytoprimitive
function 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-toprimitive
function 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 抽象操作转换为原始值,然后再根据上表进行转换。