js的強轉是我們很容易遇到坑的一個地方 比如 == 會產生很有意思的事情(使用===還是最佳實踐的)  或者+new Date()一個當前的數字時間戳  這裡面都涉及到強轉  下面分享下學習強轉的過程

簡單理解強轉   強轉是指強制將一種型別的物件或者實體轉換成另一種的行為(也就是這種轉換的行為不是你主動控制的 區別型別的顯示轉換) 在發生強轉的時候,js總是將一個複雜的物件轉化為一個基礎的型別值

        var num = 1111;
var b = "" + num;
typeof b; //string
var c = "10";
var d = +c;
typeof d; //number

js在實現強轉的時候,會通過呼叫toString()或者valueOf()返回物件的預設值,這裡面涉及到一個抽象操作ToPrimitive  下面是強轉的流程

抽象操作ToPrimitive(input,PreferredType)   -->  呼叫物件內部的[[DefaultValue]] ,[[DefaultValue]]接收PreferredType  --> 呼叫物件的ValueOf()或者toString()方法

所以當我們在建立自定義物件的,希望在轉換基本值的時候,物件能按照我們的要求去進行一些操作,就需要在物件的原型上實現toString()和valueOf()方法 並且確保他們能按照我們的意圖進行呼叫

        var person = function(name,age) {
this.name = name;
this.age = age;
};
person.prototype.toString = function() {
return 'hi' + this.name;
};
person.prototype.valueOf = function() {
return this.age;
};
var test = new person("haha",18);
console.log(+test); //18
console.log(test + ''); //18 在轉換成字串的時候和數字的時候 都呼叫了我們設定的valueOf方法 並不合理 問題出現在了toPrimitive中

下面是ES6中關於toPrimitive的描述

簡單的理解就是它會根據hint也就是PreferredType呼叫[[DefaultValue]]方法,然後呼叫toString()或者valueOf()方法  為什麼date物件上能實現可控的toString()和valueOf方法呼叫呢

在規範中對Date物件和Symbol物件進行了處理 所以他能按照我們的需要去呼叫toString()或者valueOf()方法 但是在自定義物件上呢 我們是無法傳入hint值的,在沒有hint值的情況下會預設hint值為“number”,就會導致上面的例子的出現 如果要達到我們的要求就需要一些小的技巧

插播  valueOf方法  在Object上的方法,返回物件的原始值,在js中許多的內建物件都重新定義了該方法 例如在陣列物件上呼叫valueOf方法會返回陣列的例項物件

        var test = new person("haha",18);
console.log(+test); //
console.log([test] + ''); //hihaha

通過改寫上面的例子 將test用陣列進行包裹 在toPrimitive方法的時候 會返回陣列物件  toPrimitive會繼續呼叫返回基礎值,導致對陣列每一個元素的toString()方法的呼叫 所以達到了我們的要求