toString && valueOf && Symbol.toPrimitive 辨析

咱們知道在js中,'一切皆爲對象'。每一個對象都有一個toString()方法和valueOf方法,其中toString()方法返回一個表示該對象的字符串,valueOf 方法返回該對象的原始值。bash

一、toString && valueOf 兩者的使用場景以及區別與比較

  • 對於值類型數據(又叫基本類型)場景下,toString及valueOf方法的使用
var str = "hello",n = 123,bool = true;

console.log(typeof(str.toString())+ "_"+ str.toString())        //string_hello
console.log(typeof(n.toString())+"_"+n.toString()  )            //string_123
console.log(typeof(bool.toString())+"_"+bool.toString())        //string_true
複製代碼
console.log(typeof(str.valueOf())+"_"+str.valueOf())            //string_hello
console.log(typeof(n.valueOf())+"_"+n.valueOf())                //string_123
console.log(typeof(bool.valueOf())+"_"+bool.valueOf())          //string_true

console.log(str.valueOf === str) // // true
console.log(n.valueOf === n) // // true
console.log(bool.valueOf() === bool) // true
複製代碼

toString 方法對於值類型數據使用而言,其效果至關於類型轉換,將原類型轉爲字符串。 valueOf 方法對於值類型數據使用而言,其效果將至關於返回原數據。ui

  • 複合對象類型數據使用toString及valueOf方法
var obj = {};

console.log(obj.toString());    //[object Object] 返回對象類型
console.log(obj.valueOf());     //{} 返回對象自己
複製代碼
  • 綜合案例
var test = { 
 i: 10, 
 toString: function() { 
    console.log('toString'); 
    return this.i; 
 }, 
 valueOf: function() { 
    console.log('valueOf'); 
    return this.i; 
 } 
} 
alert(test);// 10 toString 
alert(+test); // 10 valueOf 
alert(''+test); // 10 valueOf 
alert(String(test)); // 10 toString 
alert(Number(test)); // 10 valueOf 
alert(test == '10'); // true valueOf 
alert(test === '10'); // false
複製代碼

總結this

一、 在進行字符串強轉時候,優先調用toString()方法。在進行數值運算的時候,優先調用valueOf方法。
二、 再有運算符的狀況下,valueOf的優先級要高於toString()方法。
複製代碼

二、補充toString()和String()的區別

toString()方法和String()方法均可以轉換爲字符串類型。spa

(1)toString()

  • toString()能夠將全部的數據都轉換爲字符串,可是要排除nullundefined3d

  • null和undefined不能轉換爲字符串,null和undefined調用toString()方法會報錯code

  • 若是當前數據爲數字類型,則toString()括號中的能夠寫一個數字,表明進制,能夠將數字轉化爲對應進制字符串。對象

var num = 123;
console.log(num.toString()+'_'+ typeof(num.toString()));    //123_string
console.log(num.toString(2)+'_'+typeof(num.toString()));    //1111011_string
console.log(num.toString(8)+'_'+typeof(num.toString()));    //173_string
console.log(num.toString(16)+'_'+typeof(num.toString()));   //7b_string
複製代碼

(2)String()

  • String()能夠將null和undefined轉換爲字符串,可是無法轉進制字符串。

三、Symbol.toPrimitive

對象的Symbol.toPrimitive屬性。指向一個方法。該對象被轉化爲原始類型的值時,會調用這個辦法,返回該對象對應的原始類型值。 Symbol.toPrimitive被調用時,會接受一個字符串參數,表示當前運算的模式,一個有三種模式。字符串

  • Number:該場合須要轉成數值
  • String:該場合須要轉成字符串
  • Default:該場合能夠轉成數值,也能夠轉成字符串。
// 擁有 Symbol.toPrimitive 屬性的對象
var obj2 = {
  [Symbol.toPrimitive](hint) {
    if(hint == "number"){
        return 10;
    }
    if(hint == "string"){
        return "hello";
    }
    return true;
  }
}

console.log(+obj2);     //10 --hint in "number"
console.log(`${obj2}`); //hello --hint is "string"
console.log(obj2 + ""); //"true"
複製代碼
// 擁有 Symbol.toPrimitive 屬性的對象
let obj = {
  [Symbol.toPrimitive](hint) {
    if(hint === 'number'){
      console.log('Number場景');
      return 123;
    }
    if(hint === 'string'){
      console.log('String場景');
      return 'str';
    }
    if(hint === 'default'){
      console.log('Default 場景');
      return 'default';
    }
  }
}
console.log(2*obj); // Number場景 246
console.log(3 + obj); // Default 場景 3default
console.log(obj + "");  // Default場景 default
console.log(String(obj)); //String場景 str
複製代碼

由以上例子能夠總結,通常狀況下,+鏈接運算符傳入的參數是default,而對於乘法等算數運算符傳入的是number。對於String(str),${str}等狀況,傳入的參數是defalut。string

再者,Symbol.toPrimitive在類型轉換方面,優先級是最高的。it

let ab = {
    valueOf() {
        return 0;
    },
    toString() {
        return '1';
    },
    [Symbol.toPrimitive]() {
        return 2;
    }
}
console.log(1+ab); // 3
console.log('1'+ab); // 12
複製代碼
相關文章
相關標籤/搜索