今天在網上瞎逛,無心間看到一個問題:一個數字乘以一個日期等於多少?
看得內心一驚,毫無防備地被這種鬼馬精靈的問題戳中了盲點。因而趕忙研究一番。javascript
3 * new Date() // 4692361990902
複製代碼
看來結果是3乘上了時間戳。
Date的時間戳怎麼獲取呢?咱們知道是java
new Date().valueOf() // 1564120663634
複製代碼
難道是乘上了valueOf()的值?
找到了valueOf函數是在Object的原型中定義的。函數
Object.prototype.valueOf // ƒ valueOf() { [native code] }
複製代碼
是否是說3乘上一個對象,都是乘上它的valueOf()的值呢?來試一下!ui
function Test(value) {
this.value = value;
}
Test.prototype.valueOf = function() {
return this.value;
}
const test = new Test(3);
3 * test; // 9
複製代碼
的確如此!this
function Test(value) {
this.value = value;
}
const test = new Test(3);
test.valueOf(); // Test {value: 3}
3 * test; // NaN
複製代碼
返回的是對象自己。這時候3乘上它就是NaN。
常見的內置對象的valueOf值:spa
Number(3).valueOf(); // 3
String("3").valueOf(); // "3"
[1,2,3].valueOf(); // [1, 2, 3]
Boolean(3).valueOf(); // true
(function(){}).valueOf(); // ƒ (){}
({a:3}).valueOf(); // {a: 3}
...
複製代碼
從上面結果能夠粗略總結出,若是沒有對valueOf進行定義的話,那麼返回值便是對象自己。
再去看一下valueOf的文檔。
連接prototype
JavaScript calls the valueOf method to convert an object to a primitive value. You rarely need to invoke the valueOf method yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.code
valueOf是用來返回對象的原始值。難怪數字乘對象是乘以它的valueOf值。
那麼數字與幾個基本類型數據相乘會怎麼樣呢?對象
3 * null; // 0
3 * undefined; // NaN
3 * "s"; // NaN
3 * "3"; // 9
3 * true; // 3
3 * false; // 0
3 * 3; // 9
3 * NaN; // NaN
3 * {}; // NaN
3 * [3]; // 9
3 * Symbol(3); // Uncaught TypeError: Cannot convert a Symbol value to a number
複製代碼
原來是這樣,數字與基本類型數據相乘時,其餘數據又會進行類型轉換。
再把相乘順序調過來會怎樣?token
{} * 3; // Uncaught SyntaxError: Unexpected token *
複製代碼
其餘結果相同,只有這個報了錯。
({}) * 3; // NaN
複製代碼
{}是JavaScript的大括號,對不起,打擾了~~
總結一下。就是數字與對象相乘,會與對象的valueOf()相乘。基本類型之間相乘,會進行類型轉換再相乘。