2015-11-25 154 views
4

我最近看了一篇關於Object.prototype.valueOf() on MDN和感覺他們得到的東西完全錯誤的說:混淆方法Object.prototype.valueOf()

valueOf()方法返回指定的原始值目的。

我的意思是,這句話會做出一些意義,如果我們談論這個方法的更具體的版本,例如String.prototype.valueOf(),這是在原型鏈更緊密,因此將被調用,而不是Object.prototype方法,當調用String對象的valueOf方法時。在這種情況下,將運行內部算法thisStringValue並且將返回對象的內部屬性[[StringData]]的值,即基元串值。所以這實際上是從對象到原始值的轉換。

但據我瞭解,中Object.prototypevalueOf方法的工作原理完全相反方式,通過調用內部方法ToObject

現在,如果Object.prototype.valueOf()是建立在普通的對象調用時,它將調用ToObject傳入的方法中,它指向對象本身的該值,並且在這種情況下,ToObject將只返回在物體上的參考,通過toString()顯示爲[object Object]

假設我們將覆蓋String.prototype.valueOf()的值,例如Object.prototype的相關方法,然後通過調用構造函數創建String對象。 - 如果我們現在調用valueOf(),我們將返回一個對象,而不是我們作爲參數傳入的原始字符串值。就我所見,Object.prototype.valueOf()中只有ToObject,沒有從對象到原始值的轉換。

所以我得到這個權利,他們是錯的,還是我誰不明白它?

+0

有你那頁的小黃***註上閱讀***? –

+0

@ RokoC.Buljan只需將String.prototype.valueOf()替換爲Number.prototype.valueOf()即可。它是同樣的事情:如果通過調用具有參數5的構造函數創建一個Number對象並調用本地valueOf()方法,則會將數字5作爲原始值。如果用Object.prototype.valueOf()覆蓋Number方法,則會得到一個對象作爲返回值。沒有區別。 – SickBoy

+0

如果一個對象沒有在原型鏈中覆蓋這個方法,它的「原始值」就是對象本身。 – Barmar

回答

1

Object.prototype.valueOf的用途只是作爲對象的默認方法,而不會用更具體的方法覆蓋它。你不應該直接調用這個函數,當你調用一個對象的valueOf()方法時,它只是因爲在原型鏈中沒有更具體的東西而被調用。根據定義,如果一個對象沒有覆蓋它,它的「原始值」就是對象本身。

+1

這正是我認爲這種方法的目的,完全確認!正因爲如此,我認爲將所有內置對象的valueOf方法作爲一個對象是錯誤的,因爲它們的作用方式不同,這是我在我的問題中鏈接的文章中所隱含的。如果可能的話,特定版本將轉換爲原始值,但「Object.prototype」的「默認」版本將永遠不會這樣做。所以,正如我看到的那樣,說這個方法會「被調用來將一個對象轉換爲一個原始值」是錯誤的,正如在文章中所做的那樣。 - 這纔是重點。 ;-) – SickBoy

+1

我認爲問題更多的是MDN的組織。它沒有地方來記錄通用協議,它只是記錄特定的方法。但是系統如何使用這種方法的解釋應該說明清楚。 – Barmar

2

valueOf()方法返回指定對象的原始值。

請記住,MDN是由像你和我這樣的凡人寫的。我不會選擇這種方式來總結valueOf。更有意義的總結(借用下面的「說明」):

valueOf()方法返回當指定對象需要強制轉換爲原語時要使用的值。

對MDN頁面的其餘描述看起來相當合理和清晰。

從您的評論:

我認爲這是錯誤地將內置對象的所有的valueOf的方法爲一體,因爲他們不採取同樣的方式,這是我掛在文章中暗示在我的問題。

但文章本身說

每一個內置的核心對象覆蓋此方法返回一個適當的值。

因此它是而不是把它們全部視爲一體。是的,有一個valueOf接口,但它在不同的對象上有不同的實現。

這是錯誤的說法。這個方法應該「調用對象轉換爲原始值」

我沒有看到文章中完全一致的短語,但它正確的聲音,我。

0

該聲明並不完全準確,並且對於特定實現而言,如您所說的那樣「更真實」,但它是一個總結並解釋了該方法的意圖。

這是錯誤的說法。這個方法應該「稱爲一個對象轉換爲原始值」,

不,這是正確的。更確切地說:它被稱爲將對象轉換爲數字。從specs

當抽象操作OrdinaryToPrimitive被稱爲帶有參數O和提示,採取以下步驟:

  1. 斷言:類型(O)是對象

  2. 斷言:類型(提示)是字符串,其值 是「字符串」或「數字」。

  3. 如果提示是「字符串」,則讓方法名稱爲「toString」,「valueOf」»。

  4. 否則,讓方法名稱爲 «「valueOf」,「toString」»。

  5. 對於在列表中的順序每個方法名的名字,做

...

III。如果類型(結果)是而不是對象,則返回結果。

  1. 拋出TypeError異常。

沒有保證,當然,那的valueOf的實現實際上返回原始值,但是這方法是什麼。如果原型鏈中沒有其他實現,則實際上將調用Object.prototype.valueOf將對象轉換爲原始值。正如你注意到的那樣,它不起作用,但它仍然會被稱爲。

你可以自己嘗試一下:

var myObject = { 
 
     valueOf: function() { 
 
     console.log('valueOf'); 
 
     return this; 
 
     }, 
 
     toString: function() { 
 
     console.log('toString'); 
 
     return this; 
 
     } 
 
    }; 
 
    
 
1 + myObject;

會打印:

valueOf 
toString 
Uncaught TypeError: Cannot convert object to primitive value