资讯专栏INFORMATION COLUMN

[对象转原始类型总结] ('' + obj) === `${obj}`? 不一

happyhuangjinjin / 3054人阅读

摘要:一个小测试试试结论当操作需要一个字符串时当操作需要一个数字时当运算符不确定时如果存在就直接调用如果是先调用没有再调用如果是先调用没有再调用如果是按照处理其它按照处理如果或者返回的不是原始类型则忽略该调用转向下一个调用如果没有下一个调用则报

一个小测试, 试试:

let o = {
  valueOf() {
    return 0;
  },
};
console.log(+o); // 0
console.log(1 + o); // 1
console.log(1 - o); // 1
console.log("" + o); // "0"
console.log(`${o}`); // "[object Object]"
结论

当操作需要一个字符串时, hint=string, 当操作需要一个数字时, hint=number, 当运算符不确定时hint=default.

如果存在 obj[Symbol.toPrimitive](hint), 就直接调用

如果 hintstring, 先调用 obj.toString(), 没有再调用 obj.valueOf()

如果 hintnumber, 先调用 obj.valueOf(), 没有再调用obj.toString()

如果 hintdefault, Date 按照 hint=string处理, 其它按照 hint=number 处理

如果 toString 或者 valueOf 返回的不是原始类型, 则忽略该调用, 转向下一个调用, 如果没有下一个调用, 则报错, 但是 toPrimitive 必须返回原始类型, 否则报错

详解 根据上下文, 会有以下转换 hint string

当操作需要一个字符串时, 对象转换的 hintstring.

// alert(参数是字符串)
alert(obj);
confirm(obj);

// 对象的属性是字符串
anotherObj[obj] = 123;
number

当操作需要一个数字时, 对象转换的 hintnumber.

// 明确转换成数字
Number(obj);
// 转换成数字(非加法)
+obj;
// 数学运算(加法除外)
1 - obj;
1 * obj;
1 / obj;

因为历史原因大小比较的 hint 也是 number

// hint 为 number
obj1 > obj2;
default

当运算符不确定时, 对象转换的 hintdefault.

// 比如加法, 可以是数字相加, 也可以是字符串相加
1 + obj;
"1" + obj;

// == 弱相等比较
// obj == string/number/symbol
obj == "1";
obj == 1;

通常, 内置对象(除了 Date 外), default 转换 和 number 转换是相同的
Date 的 default 转换 和 string 相同 [Date.prototype[@@toPrimitive]](https://developer.mozilla.org...

转换步骤

如果存在 obj[Symbol.toPrimitive](hint), 就直接调用

如果 hintstring, 先调用 obj.toString(), 没有再调用 obj.valueOf()

如果 hintnumber, 先抵用 obj.valueOf(), 没有再调用obj.toString()

example Symbol.toPrimitive
type primitiveType = null | undefined | number | boolean | string | symbol;
type hintType = "string" | "number" | "default";

obj[Symbol.toPrimitive] = function(hint: hintType): primitiveType {
  console.log(`hint is: ${hint}`);

  return hint == "string" ? "一个字符串" : 0;
};
toString / valueOf
let user = {
  name: "John",
  money: 1000,

  // for hint="string"
  toString(): string {
    return `{name: "${this.name}"}`;
  },

  // for hint="number" or "default"
  valueOf(): number {
    return this.money;
  },
};

alert(user); // toString -> {name: "John"}
alert(+user); // valueOf -> 1000
alert(user + 500); // valueOf -> 1500
let obj = {
  toString() {
    return "2";
  },
};

// 加法, 调用 `default` hint, `default` 和 `number` 转换相同,
// 先调用 valueOf 方法, 因为不存在, 所以调用 toString 方法, 返回 "2"
// "2" + 2 = "22"
alert(obj + 2); // "22"

// 存在 valueOf, 所以 2+2 = 4
let obj = {
  toString() {
    return "2";
  },
  valueOf() {
    return 2;
  },
};

alert(obj + 2); // 4
let d = new Date();
let d2 = d.getTime() - 1;

// 加法, 调用 `default` hint, Date 的 `default` 和 `string` 相同
alert(1 + d); // 1Fri Feb 15 2019 20:59:00 GMT+0800 (China Standard Time)

// 减法, 调用 `number` hint
alert(d - d2); // 1
参考文档

https://javascript.info/object-toprimitive

[Date.prototype[@@toPrimitive]](https://developer.mozilla.org...

文章若有纰漏请大家补充指正,谢谢~~  
http://blog.xinshangshangxin.com SHANG 殇

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101730.html

相关文章

  • '{ }'在不同上下文中的作用

    摘要:大括号的作用,在不同的上下文中差别很大以下观点若有错误,请前辈及时指出一被当做对象字面量如,外层的被赋值给了,这里的被当做对象处理。本文参考你不知道的 大括号‘{ }’的作用,在不同的上下文中差别很大!以下观点若有错误,请前辈及时指出! 一、{ }被当做对象字面量 如:var obj = { foo: function(){} };,外层的{...}被赋值给了obj,这里的{...}被...

    Reducto 评论0 收藏0
  • 《You Don't Know JS》阅读理解——this

    摘要:运行规则根据的运作原理,我们可以看到,的值和调用栈通过哪些函数的调用运行到调用当前函数的过程以及如何被调用有关。 1. this的诞生 假设我们有一个speak函数,通过this的运行机制,当使用不同的方法调用它时,我们可以灵活的输出不同的name。 var me = {name: me}; function speak() { console.log(this.name); }...

    tianren124 评论0 收藏0
  • <<编写可维护的javascript>> 笔记8(避免&#039;空比较&#

    摘要:中常常会看到这种代码变量与的比较这种用法很有问题用来判断变量是否被赋予了一个合理的值比如不好的写法执行一些逻辑这段代码中方法显然是希望是一个数组因为我们看到的拥有和这段代码的意图非常明显如果参数不是一个数组则停止接下来的操作这种写法的问题在 js中, 常常会看到这种代码: 变量与null的比较(这种用法很有问题), 用来判断变量是否被赋予了一个合理的值. 比如: const Contr...

    young.li 评论0 收藏0
  • ( 第二篇 )仿写&#039;Vue生态&#039;系列___&#039;模板小故事.&#039;

    摘要:第二篇仿写生态系列模板小故事本次任务承上完成第一篇未完成的热更新配置核心完成模板解析模块的相关编写很多文章对模板的解析阐述的都太浅了本次我们一起来深入讨论一下尽可能多的识别用户的语句启下在结构上为双向绑定等模块的编写打基础最终效果图一模板页 ( 第二篇 )仿写Vue生态系列___模板小故事. 本次任务 承上: 完成第一篇未完成的热更新配置. 核心: 完成模板解析模块的相关编写, ...

    wangtdgoodluck 评论0 收藏0
  • ( 第二篇 )仿写&#039;Vue生态&#039;系列___&#039;模板小故事.&#039;

    摘要:第二篇仿写生态系列模板小故事本次任务承上完成第一篇未完成的热更新配置核心完成模板解析模块的相关编写很多文章对模板的解析阐述的都太浅了本次我们一起来深入讨论一下尽可能多的识别用户的语句启下在结构上为双向绑定等模块的编写打基础最终效果图一模板页 ( 第二篇 )仿写Vue生态系列___模板小故事. 本次任务 承上: 完成第一篇未完成的热更新配置. 核心: 完成模板解析模块的相关编写, ...

    ivydom 评论0 收藏0

发表评论

0条评论

happyhuangjinjin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<