彻底搞懂 JS 类型转换( 六 )

mySymbol 转换为字符串,并且在检测到强制转换时会抛出错误,从而阻止以这种方式使用它 。
同样,我们不能将 symbol 强制转换为数字,所有数学运算符在与符号一起使用时都会引发错误:
const mySymbol = Symbol.for("mySymbol");const factor = mySymbol / 2;console.log(factor);   // Uncaught TypeError: Cannot convert a Symbol value to a number4. 对象类型转换介绍完了基本数组类型的转化 , 下面来看看对象类型的转化 。例如 , 当执行 obj_1 + obj_2 或者 obj_1 - obj_2时,都会先将对象转换为原始类型,然后将其转换为最终类型 。当然,这里的转化仍然只有三种类型:数字、字符串和布尔值 。
对象通过内部的 ToPrimitive 方法将其转换为原始类型,该算法允许我们根据使用对象的上下文来选择应如何转换对象 。从概念上讲 , ToPrimitive 算法可以分为两部分:Hints 和 Object-to-primitive 转换方法 。


彻底搞懂 JS 类型转换

文章插图
(1)HintsHints 是 ToPrimitive 算法用于确定对象在特定上下文中应转换为什么的信号 。有三种情况:
  • string:在操作需要字符串的上下文中,如果可以转换为字符串 , 例如 alert() 或内置 String() 函数:
alert(obj);String(obj)// 使用对象作为属性key值anotherObj[obj] = 1000;
  • number:如果可以进行这种转换 , 则在操作需要数字的上下文中:
// 显示转换let num = Number(obj);// 数学(二进制加号除外)let x = +obj; // 一元加let difference = Date1 - Date2; // 日期对象// 对象大小比较let less = Obj1 < obj2;
  • default:在极少数情况下发生 , 不确定需要什么类型 。例如 , 二元 + 运算符既适用于字符串(连接它们)也适用于数字(添加它们) 。在这种情况下 , 对象可以转换为字符串或数字 。或者当使用宽松相等 == 运算符将对象与字符串、数字或 symbol 进行比较时 。
// 二元加let sum = obj1 + obj2;// obj == string/number/symbolif (obj == 10 ) { ... };所有内置对象(日期除外)都将default认为是number , Date 日期对象将default认为是string
(2)Methods在 ToPrimitive 算法根据 Hints 确定对象应转换为的原始值类型之后 。然后使用 Object-to-primitive 转换方法将对象转换为原始值 。有三种情况:
  • toString/valueOftoString() 和 valueOf() 被 JavaScript 中的所有对象继承 。它们仅用于对象到原始值的转换 。ToPrimitive 算法首先会尝试 toString() 方法 。如果定义了方法,它返回一个原始值 , 那么 JavaScript 使用原始值(即使它不是字符串) 。如果toString() 返回一个对象或不存在,那么 JavaScript 会尝试使用 valueOf() 方法,如果该方法存在并返回一个原始值,JavaScript 将使用该值 。否则 , 转换失败并提示 TypeError
  • toString -> valueOf:用于 Hints 为string 的情况 。
  • valueOf -> toString:其他情况 。
let Person = {  name: "Mary",  age: 22,  // hint 是 "string"  toString() {    return `{name: "${this.name}"}`;  },  // hint 是 "number" 或 "default"  valueOf() {    return this.age;  }};alert(Person);      // toString -> {name: "Mary"}alert(+Person);     // valueOf -> 22alert(Person + 10); // valueOf -> 32在上面的代码中,


推荐阅读