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()方法的呼叫 所以達到了我們的要求