阅读 75

对象转原始类型toPrimitive

JavaScript 对象转换到基本类型值时,会使用 ToPrimitive 算法

toPrimitive 是个抽象的操作 可通过使用Symbol.toPrimitive自定义

// 伪代码 /**  * toPrimitive   * @param {Object} input 如果非object类型则直接返回  * @param {string} [preferredType] 首选类型,需装换的基本类型  **/ function toPrimitive(input, preferredType) {   const exoticToPrim = input[Symbol.toPrimitive]   if (exoticToPrim) {     let hint     if (!preferredType) {       hint = 'default'     } else {       // 这里没有判断number 是因为       // Symbol.toPrimitive的hint 一定是 "number"、"string" 和 "default"中任意一个       hint = preferredType === 'string' ? 'string' : 'number'     }     const result = exoticToPrim(hint)     if (typeof result !== 'object') { return result }     throw new TypeError('error')   }   if (!preferredType) {     preferredType = 'number'   }   return OrdinaryToPrimitive(input, preferredType) } 复制代码

toPrimitive 处理流程

  1. 如果input为Object类型时

    1. 如果没有指定需要装换的基本类型(preferredType),则让hint为"default"

    2. 如果装换的基本类型(preferredType)为string,则让hint为"string"

    3. 如果装换的基本类型(preferredType)为number,则让hint为"number"

    4. 调用exoticToPrim得到result

    5. 如果result不是Object类型则返回 result

    6. 如果还是Object类型则抛出异常TypeError

    7. 是否存在外部定义的toPrimitive(exoticToPrim)? 这里指是否定义Symbol.toPrimitive

    8. 如果exoticToPrim定义了,则

    9. 如果不存在 preferredType 则 把preferredType 当"number"处理

    10. 调用OrdinaryToPrimitive(input, preferredType) 的结果当返回值

  2. 非object则直接return input

// 伪代码 /**  * 默认toPrimitive  * @param {Object} O 对象  * @param {string} hint 转的类型  **/ function OrdinaryToPrimitive(O, hint) {   const methodNames = hint === 'string'     ? ['toString', 'valueOf']     : ['valueOf', 'toString']   for (let i = 0; i < methodNames.length; i++) {     let name = methodNames[i]     if (typeof O[name] === 'function') {       const result = O[name]()       if (typeof result !== 'object') {         return result       }     }   }   throw new TypeError('error') } 复制代码

OrdinaryToPrimitive处理流程

  1. 如果hint为String

    1. 则定义methodNames为 [toString, valueOf]

  2. 否则

    1. 则定义methodNames为 [valueOf, toString]

  3. 遍历 methodNames, 对于每个元素声明为name

    1. 调用method结果定义为result

    2. 如果result不为Object,则返回 result

    3. 获取O内的name定义为method

    4. 如果method为可调用的方法

  4. 最后抛出异常TypeError


作者:Stay hungry.Stay fooli
链接:https://juejin.cn/post/7022835394609692686


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐