这个特性来自与和朋友聊天时对方发送过来的一个链接:fix(vite-node): coerce to string in import(dep) by jcbhmr · Pull Request #3430 · vitest-dev/vitest · GitHub

这里 import 了一个对象

import({ toString:() => 'node:util' })

这种写法我感觉不应该这样写的,虽然官方支持这种写法,也能正常运行,但是正常写还是好一点

import('node:util')

特性说明

MDN描述Symbol.toPrimitive - JavaScript | MDN

JavaScript提供了一种特殊的机制来控制对象被转换为原始值(基本类型)的方式。 Symbol.toPrimitive 是一个内置的 Symbol值,在对象中定义了一个方法,这个方法决定了对象在转换为原始值时的行为

当我们尝试将一个对象转换为原始值时,Symbol.toPrimitive 允许我们自定义转换的行为,JavaScript 引擎会自动查找对象中是否存在 toPrimitive 方法。
这个方法接收一个参数,表示对象在进行转换时的预期类型:

  • number
  • string
  • default

示例

const obj = {
 value: 10,
  [Symbol.toPrimitive](hint) {
    if (hint === "number") {
      return 99;
    }
    if (hint === "string") {
      return "Hello Word";
    }
    return this.value.toString();
  },
};
console.log(+obj); // 99 对象被转换为数字 99
console.log(`${obj}`); // "Hello Word" - 对象被转换为字符串
console.log(obj); // { value: 10 }    — 对象被转换为默认值

上面的示例中:

  • 当我们对obj做加法运算时,预期转换的类型为number,返回数字 99;
  • 当我们预期将obj转换 string 时,返回字符串 Hello Word;
  • 如果预期类型为 default,则会根据具体的定义返回默认值;

Symbol.toPrimitive 提供了一种灵活的方式来控制对象的的类型转换行为,使得对象在不同的上下文中能够以我们期望的方式进行转换。

使用场景

一、类型转化操作
当我们对对象执行类型转换操作时,例如将对象转换为字符串、数字或者布尔值时,可以用这个特性来控制我们的转换结果
二、运算符操作
在某些运算符操作中,对象可能需要转化成原始值,例如当进行算术运算、比较运算或者逻辑运算时,对象会被自动转换为基本类型,Symbol.toPrimitive 允许我们自定义这些行为
三、字符串拼接
在字符串拼接操作中,如果对象参与了拼接,那么会直接将对象转换为字符串,使用 Symbol.toPrimitive 可以控制对象转换为字符串的行为和结果

考虑下 toString 方法

const obj = {
	toString: () => 99
}
 
obj + ''; // 99
`${obj}`; // 99