对象转原始类型

栏目: JavaScript · 发布时间: 6年前

内容简介:对象转原始类型时, 会发生什么?当操作需要一个字符串时, 对象转换的当操作需要一个数字时, 对象转换的

对象转原始类型时, 会发生什么?

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]'

结论

  1. 当操作需要一个字符串时, hint = string , 当操作需要一个数字时, hint = number , 当运算符不确定时 hint = default .
  2. 如果存在 obj[Symbol.toPrimitive](hint) , 就直接调用
  3. 如果 hintstring , 先调用 obj.toString() , 没有再调用 obj.valueOf()
  4. 如果 hintnumber , 先调用 obj.valueOf() , 没有再调用 obj.toString()
  5. 如果 hintdefault , Date 按照 hint=string 处理, 其它按照 hint=number 处理
  6. 如果 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] _

转换步骤

  1. 如果存在 obj[Symbol.toPrimitive](hint) , 就直接调用
  2. 如果 hintstring , 先调用 obj.toString() , 没有再调用 obj.valueOf()
  3. 如果 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

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序设计方法(中文版)

程序设计方法(中文版)

Matthias Fellisen / 黄林鹏、朱崇恺 / 人民邮电出版社 / 2003-12 / 49.00元

《程序设计方法》以Scheme语言为基础介绍计算和程序设计的一般理论和实践。《程序设计方法》由8个部分和7个独立的章节(第8、13、18、24、29、33、38章)组成。8个部分主要讨论程序设计,独立章节则介绍一些与程序设计和计算相关的话题。《程序设计方法》第1至第3部分介绍了基于数据驱动的程序设计基础。第4部分介绍了程序设计中的抽象问题。第5部分和第6部分是与递归及累积相关的内容。《程序设计方法......一起来看看 《程序设计方法(中文版)》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具