# Object to primitive conversion

## ToPrimitive

轉換為字串或數字得的演算法為 `ToPrimitive`，物件被使用在需要原始值的情況時，會自動轉換。

```javascript
//String
// output
alert(obj);

// using object as a property key
anotherObj[obj] = 123;

// number
// explicit conversion
let num = Number(obj);

// maths (except binary plus)
let n = +obj; // unary plus
let delta = date1 - date2;

// less/greater comparison
let greater = user1 > user2;

// default
// binary plus
let total = car1 + car2;

// obj == string/number/symbol
if (user == 1) { ... };

// 除了 Date 物件，所有 default 都和 number 轉換一致，可視為只有 2 種轉換，number and string
```

JavaScript 有 3 種轉換類型的方法

1. Call `obj[Symbol.toPrimitive](hint)` if the method exists,
2. Otherwise if hint is `"string"`
   * try `obj.toString()` and `obj.valueOf()`, whatever exists.
3. Otherwise if hint is `"number"` or `"default"`
   * try `obj.valueOf()` and `obj.toString()`, whatever exists.

## Symbol.toPrimitive

```javascript
obj[Symbol.toPrimitive] = function(hint) {
  // return a primitive value
  // hint = one of "string", "number", "default"
}

let user = {
  name: "John",
  money: 1000,

  [Symbol.toPrimitive](hint) {
    alert(`hint: ${hint}`);
    return hint == "string" ? `{name: "${this.name}"}` : this.money;
  }
};

// conversions demo:
alert(user); // hint: string -> {name: "John"}
alert(+user); // hint: number -> 1000
alert(user + 500); // hint: default -> 1500
```

## toString/valueOf

`toString` and `valueOf` 來自上古時代，如果沒有 `Symbol.toPrimitive` ，JavaScript 會尋找這 2 種方法來轉換類型。

```javascript
let user = {
  name: "John",
  money: 1000,

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

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

};

alert(user); // toString -> {name: "John"}
alert(+user); // valueOf -> 1000
alert(user + 500); // valueOf -> 1500

// 只想要一個可以轉換成原始值的方法，用 toString
let user = {
  name: "John",

  toString() {
    return this.name;
  }
};

alert(user); // toString -> John
alert(user + 500); // toString -> John500
```

## Further operations

原始值轉換不一定返回 hint 的值，沒有限制 `toString` 一定要返回 string 或 hint 是 number`Symbol.toPrimitive` 一定返回 number，唯一的事實是一定會返回原始值。

```javascript
// number
let obj = {
  toString() { // toString handles all conversions in the absence of other methods
    return "2";
  }
};

alert(obj * 2); // 4, ToPrimitive gives "2", then it becomes 2

// string
let obj = {
  toString() {
    return "2";
  }
};

alert(obj + 2); // 22 (ToPrimitive returned string => concatenation)

// number
let obj = {
  toString() {
    return true;
  }
};

alert(obj + 2); // 3 (ToPrimitive returned boolean, not string => ToNumber)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mistborn.gitbook.io/til-coding/javascript/object-to-primitive-conversion.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
