toString()和valueOf()函式呼叫和優先順序

wade3po發表於2019-04-03

最近水群的時候看見了一個題目:

add(2)(3)(4);

簡單了說就是鏈式呼叫,鏈式呼叫的方法有很多,jQuery的,underscore的和lodash這三個庫採用了不同的方式。而上面這個就簡單多了:

function add(x) { 

  var sum = x; 

  var tmp = function (y) {  

  sum = sum + y; 

    return tmp;  

  };    

tmp.toString = function () {   

   return sum;    

}; 

   return tmp;

}
複製程式碼

這邊只是使用了輸出或者是運算的時候型別的轉換。

JavaScript中幾乎所有的物件都繼承了toString和valueOf這兩個方法:

valueOf()會把資料型別轉換成原始型別

toString()會把資料型別轉換成string型別

需要注意的是,這兩個方法在不同使用場景會有不同的優先順序:

正常情況下,優先呼叫toString()

有運算操作符的情況下valueOf()的優先順序高於toString()

當呼叫valueOf()方法無法運算後還是會再呼叫toString()方法

我們可以改寫這兩個方法測試優先順序:

var n = { 

   toString: function () { 

       return 1 

   }, 

   valueOf: function () {  

      return 2 

   }

}

var obj = {1: 1, 2: 2};

console.log(+n);//1

console.log(obj[n]);//2
複製程式碼

除了上面三個方法之外,還是有一些會比較特殊,比如Date,應該還有很多我還不知道的優先順序:

var date=new Date();

date.valueOf = function(){  

  return '1000'

}

console.log(+date);
複製程式碼

大概知道這兩個方法之後,迴歸這個函式:

function add(x) {  

  var sum = x; 

   var tmp = function (y) { 

    sum = sum + y; 

     return tmp;  

  };

  tmp.toString = function () { 

   return sum;   

 };

  return tmp;

}
複製程式碼

呼叫:add(5)(3)(2)

其實add(5)是一個函式

console.log(typeof add(5));//function

是這個函式:

function (y) {  

  sum = sum + y; 

   return tmp;

};
複製程式碼

因為閉包的原因,tmp和sum都被存起來了。所以我們可以鏈式呼叫。

add(5)(2)(3);

當我們執行完畢,想要運算或者是輸出的時候,就會執行toString方法。

tmp.toString = function () {  

  console.log('toString')  

  return sum;

};
複製程式碼

然後執行輸出或者是運算:

add(5)(2) + add(5)(3);//toString toString

但是不同瀏覽器會有不同的結果,火狐上面:

console.log(add(5)(4));

toString()和valueOf()函式呼叫和優先順序
不進行運算是不會呼叫toString的。

Coding 個人筆記

toString()和valueOf()函式呼叫和優先順序

相關文章