聊一聊valueOf和toString

前言

在ECMAScript中,引用類型是一種數據結構,用於將數據和功能組織在一起。Object 是ECMAScript中使用最多的一個類型,雖然Object的實例不具備多少功能,但對於在應用程序中存儲和傳輸數據而言,他們確實是非常理想的選擇。

基本上,所有JS數據類型都擁有這兩個方法,null除外。它們倆解決javascript值運算與顯示的問題,重寫會加大它們調用的優化。

測試分析

先看一例:

var aaa = { 
 i: 10, 
 valueOf: function() { return this.i+30; }, 
 toString: function() { return this.valueOf()+10; } 
} 

alert(aaa > 20); // true 
alert(+aaa); // 40 
alert(aaa); // 50 

之所以有這樣的結果,因爲它們偷偷地調用valueOf或toString方法。
但如何區分什麼情況下是調用了哪個方法呢,我們可以通過另一個方法測試一下。

var bbb = {
 i: 10,
 toString: function() {
  console.log('toString');
  return this.i;
 },
 valueOf: function() {
  console.log('valueOf');
  return this.i;
 }
}

alert(bbb);// 10 toString
alert(+bbb); // 10 valueOf
alert(''+bbb); // 10 valueOf
alert(String(bbb)); // 10 toString
alert(Number(bbb)); // 10 valueOf
alert(bbb == '10'); // true valueOf
alert(bbb === '10'); // false

結果給人的感覺是,如果轉換爲字符串時調用toString方法,如果是轉換爲數值時則調用valueOf方法,但其中有兩個很不和諧。一個是alert(’’+bbb),字符串合拼應該是調用toString方法……另一個我們暫時可以理解爲===操作符不進行隱式轉換,因此不調用它們。爲了追究真相,我們需要更嚴謹的實驗。

var aa = { 
 i: 10, 
 toString: function() { 
  console.log('toString'); 
  return this.i; 
 } 
} 
alert(aa);// 10 toString 
alert(+aa); // 10 toString 
alert(''+aa); // 10 toString 
alert(String(aa)); // 10 toString 
alert(Number(aa)); // 10 toString 
alert(aa == '10'); // true toString 

再看valueOf。

var bb = { 
 i: 10, 
 valueOf: function() { 
  console.log('valueOf'); 
  return this.i; 
 } 
} 

alert(bb);// [object Object] 
alert(+bb); // 10 valueOf 
alert(''+bb); // 10 valueOf 
alert(String(bb)); // [object Object] 
alert(Number(bb)); // 10 valueOf 
alert(bb == '10'); // true valueOf 

發現有點不同吧?!它沒有像上面toString那樣統一規整。
對於那個[object Object],我估計是從Object那裏繼承過來的,我們再去掉它看看。

Object.prototype.toString = null; 
var cc = { 
 i: 10, 
 valueOf: function() { 
  console.log('valueOf'); 
  return this.i; 
 } 
} 

alert(cc);// 10 valueOf 
alert(+cc); // 10 valueOf 
alert(''+cc); // 10 valueOf 
alert(String(cc)); // 10 valueOf 
alert(Number(cc)); // 10 valueOf 
alert(cc == '10'); // true valueOf 

總結:valueOf偏向於運算,toString偏向於顯示。

1、 在進行對象轉換時(例如:alert(a)),將優先調用toString方法,如若沒有重寫toString將調用valueOf方法,如果兩方法都不沒有重寫,但按Object的toString輸出。
2、 在進行強轉字符串類型時將優先調用toString方法,強轉爲數字時優先調用valueOf。
3、 在有運算操作符的情況下,valueOf的優先級高於toString。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章