[对象转原始类型总结] ('' + obj) === `${obj}`? 不一定!
一个小测试, 试试:
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)
, 就直接调用 - 如果
hint
是string
, 先调用obj.toString()
, 没有再调用obj.valueOf()
- 如果
hint
是number
, 先调用obj.valueOf()
, 没有再调用obj.toString()
- 如果
hint
是default
,Date
按照hint=string
处理, 其它按照hint=number
处理 - 如果
toString
或者valueOf
返回的不是原始类型, 则忽略该调用, 转向下一个调用, 如果没有下一个调用, 则报错, 但是toPrimitive
必须返回原始类型, 否则报错
详解
根据上下文, 会有以下转换 hint
string
当操作需要一个字符串时, 对象转换的 hint
为 string
.
// alert(参数是字符串)
alert(obj);
confirm(obj);// 对象的属性是字符串
anotherObj[obj] = 123;
number
当操作需要一个数字时, 对象转换的 hint
为 number
.
// 明确转换成数字
Number(obj);
// 转换成数字(非加法)
+obj;
// 数学运算(加法除外)
1 - obj;
1 * obj;
1 / obj;
因为历史原因大小比较的 hint
也是 number
// hint 为 number
obj1 > obj2;
default
当运算符不确定时, 对象转换的 hint
为 default
.
// 比如加法, 可以是数字相加, 也可以是字符串相加
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)
, 就直接调用 - 如果
hint
是string
, 先调用obj.toString()
, 没有再调用obj.valueOf()
- 如果
hint
是number
, 先抵用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 殇
[对象转原始类型总结] ('' + obj) === `${obj}`? 不一定!相关推荐
- 【前端2】js:原始类型,运算符,调试,页面加载,轮播图,Bom(对象,时钟),Dom(全选全不选,省市级联,隔行/触摸换色,表单校验)
文章目录 1.js两种引入:js最终要引入到html在浏览器中运行 2.js五大原始类型:undefined 3.js的运算符和流程控制:js不支持单&和单|性能低 4.案例_99乘法表:So ...
- 理解JavaScript的原始类型
2019独角兽企业重金招聘Python工程师标准>>> JavaScript中的原始类型(primitive type)包括Undefined.Null.Number.Boolean ...
- java解包_Java的原始类型自动包装与解包机制
java5之后对原始数据类型如int.char.long等基本数据类型有自动打包成相应的复合类型Integer.Character.Long等的机制:也可以将复合类型自动转换为原始类型. 这取决于程序 ...
- java在何时获得对象的确切类型_JAVA面试题(1)
基础部分 面向对象 1.谈谈你对多态的理解. 答:在java中对于多态的理解是很重要的 多态的定义: 允许不同类的对象对同一消息做出相应,同一消息可以根据发送对象的不同而采用多种不同的行为方式,(发送 ...
- 《JavaScript高级程序设计》阅读笔记(二):ECMAScript中的原始类型
2.6 原始类型 ECMAScript有5种原始类型(primitive type),即Undefined.Null.Boolean.Number和String.ECMAScript提供了typeof ...
- 《JavaScript面向对象精要》——第1章 原始类型和引用类型1.1 什么是类型
本节书摘来自异步社区<JavaScript面向对象精要>一书中的第1章,第1.1节,作者:[美]Nicholas C. Zakas 译者: 胡世杰 更多章节内容可以访问云栖社区" ...
- 如何区分引用类型和原始类型
下表列出了原始类型以及它们的对象封装类. 原始类型和封装类 原始类型 封装类 boolean Boolean char Character byte Byte short Short int Inte ...
- ECMAScript 基础--原始类型
ECMAScript 有 5 种原始类型(primitive type),即 Undefined.Null.Boolean.Number 和 String. typeof 运算符 对变量或值调用 ty ...
- c# 变量,对象,静态类型,集合类的线程安全回顾
1.变量的线程安全性与变量的作用域有关. 2.对象 对象是类型的实例 在创建对象时,会单独有内存区域存储对象的属性和方法.所以,一个类型的多个实例,在执行时,只要没有静态变量的参与,应该都是线程安全的 ...
最新文章
- Node.js模块化开发||Node.js中模块化开发规范
- 【Pytorch神经网络理论篇】 03 Pytorch快速上手(三)张量的数据操作
- freemaker中小数展示为整数的问题
- git 初始化git存储库_什么不保存到Git存储库中
- 随机组卷功能,你值得拥有~~~
- mysql infobright 缺点_Infobright存储引擎的特点
- mysql 部署最佳实践_MySQL安装脚本最佳实践
- ios safari 模拟器_Safari调试iOS应用
- C++学习笔记:实现向量类的加减赋值运算,重载运算符
- 最优秀的6410开发板全球震撼首发!
- RTSP安防网络摄像头/海康大华硬盘录像机/NVR网页无插件低延时播放流媒体服务器EasyNVR页面显示网络请求失败问题
- 入职快手半年工作小结
- 贪吃蛇小程序·C/C++
- 简体中文转换繁体中文
- 夺神之权服务器维护,流放之路3月28日夺神之权停服更新详解
- 使用JDBC完成数据的增加
- zxing生成二维码去白边
- 药房药品管理信息系统
- 理化试验室计算机维护保养,实验室常用仪器的维护保养
- 亚马逊平台在哪个站点开店好
热门文章
- nand flash和nor flash区别_从闪存的发展历史看,eMMC与NAND Flash有什么区别与联系?...
- linux 路由跟踪命令_一文掌握linux系统路由跟踪指令traceroute
- cesium加载 gltf模型
- oracle替换指定字符串字符_实例:替换方框内字符串内容
- python定义test方法_关于python:使用pytest测试类方法
- vscode 不支持的客户端_Windows平台上有哪些你不知道的神器?
- 视频抽帧并存图 python_使用Python实现跳帧截取视频帧
- 若依微服务部署遇到问题
- 2016考试计算机知识基础题库,2016年计算机二级公共基础知识基础练习题演练(6)...
- python后端程序例子_Python MR程序示例