100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > [对象转原始类型总结] ('' + obj) === `${obj}`? 不一定!

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

时间:2023-11-01 12:31:04

相关推荐

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

一个小测试, 试试:

let o = {valueOf() {return 0;},};console.log(+o); // 0console.log(1 + o); // 1console.log(1 - o); // 1console.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 为 numberobj1 > obj2;

default

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

// 比如加法, 可以是数字相加, 也可以是字符串相加1 + obj;'1' + obj;// == 弱相等比较// obj == string/number/symbolobj == '1';obj == 1;

通常, 内置对象(除了 Date 外),default转换 和number转换是相同的

Date 的default转换 和string相同 [Date.prototype[@@toPrimitive]](...

转换步骤

如果存在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 -> 1000alert(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 = 4let 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 20:59:00 GMT+0800 (China Standard Time)// 减法, 调用 `number` hintalert(d - d2); // 1

参考文档

https://javascript.info/object-toprimitive[Date.prototype[@@toPrimitive]](...
文章若有纰漏请大家补充指正,谢谢~~

SHANG 殇

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。