2011-12-20 63 views
5

這個問題已經出來了another,其中涉及console.dir與字符串文字的行爲。尤其請參閱my answer的評論。爲什麼String.prototype的方法可用於字符串文字?

衆所周知,String JavaScript中的對象有許多方法。這些方法在String.prototype對象上定義。例如,String.prototype.toUpperCase。因此,我們可以做這樣的事情:

var s = new String("hello"), 
    s2 = s.toUpperCase();  //toUpperCase is a method on String.prototype 

但是,我們也可以這樣做:

var s = "hello",    //s is a string literal, not an instance of String 
    s2 = s.toUpperCase(); 

顯然,JavaScript解釋正在做某種形式的轉換/施放的,當你調用String.prototype的方法在字符串文字上。但是,我在spec中找不到任何對此的提及。

它是有道理的,因爲否則,在使用任何方法之前,您必須明確地將每個字符串文字轉換爲String對象,並且這會很煩人。

所以我的問題是,這個功能描述在哪裏,我是否正確地假設文字值暫時被轉換爲String的實例?我是否過度思考這一點,並忽略了一些明顯的東西

+1

順便說一句'新的字符串(值)'表示法是100%無用的...不要使用它。 – 2011-12-20 21:00:20

+0

我知道是。問題是爲什麼。規範中描述了哪些內容? – 2011-12-20 21:00:56

+1

字符串文字是一個字符串對象:'typeof「hello」===「string」'返回true。這是否解決了這個問題? – bbg 2011-12-20 21:01:35

回答

7

它定義這裏:

以下[[獲取]]內部方法用於在getValue當V是與圖元鹼值的 屬性參考。它被稱爲使用 基地作爲它的這個值並且以屬性P作爲它的參數。採取以下步驟 :

  1. 設O爲ToObject(base)。
  2. 設desc爲調用屬性名稱爲P的[[GetProperty]]的內部方法的結果。
  3. 如果desc未定義,則返回undefined。
  4. 如果IsDataDescriptor(desc)爲true,則返回desc。[[Value]]。
  5. 否則,IsAccessorDescriptor(desc)必須爲真,因此,讓getter被描述爲[[Get]]。
  6. 如果getter未定義,則返回undefined。
  7. 返回調用getter提供庫的[[Call]]內部方法的結果作爲該值並且不提供參數。

注意在上述方法之外,可能在步驟1中創建的對象不可訪問 。實現可能會選擇避免實際創建對象。使用此內部方法的這種實際屬性訪問唯一可見的 效果是當它調用訪問器函數時。

來源:http://es5.github.com/#x8.7.1

的原始字符串值被強制轉換到對象在步驟1


實施例1

var str = 'some string'; 
str = str.toUpperCase(); 

這裏,表述str.toUpperCase是根據在11.2.1 Property Accessors定義的語義進行評估:

  1. 標識符str根據標識符解析(見10.2.2.1 GetIdentifierReference)來評價。結果是一個引用,其基值是當前詞彙環境的環境記錄,其引用名稱爲"str"。該參考文獻是baseReference
  2. baseValue通過執行GetValue(baseReference)來確定。由於baseReference不是屬性引用(其基本值不是對象或原始值,而是環境記錄),因此將調用GetBindingValue()方法以檢索引用的值。該方法返回局部變量str的值,即基元字符串值'some string'。該值是baseValue
  3. propertyNameValue求值爲原始字符串值'toUpperCase'。 (爲簡單起見,我略微縮短了此過程。)
  4. 創建一個新的引用,其基值爲baseValue,其引用的名稱爲propertyNameValue

因此,有參與這一進程的兩個引用:

  • str(基值:環境記錄,引用名稱:'str'
  • str.toUpperCase(基值:'some string',引用的名字: 'toUpperCase'

最後,調用運算符()在後面的引用上執行。該引用的值根據此答案頂部定義的語義確定。

實施例2

var str = 'some string'.toUpperCase(); 

這裏,表述'some string'.toUpperCase根據相同的 「屬性訪問」 的語義被評估如實施例1:

  1. 的字符串文字'some string'明顯計算結果爲原始字符串值'some string'。這是baseReference。 (不要讓名稱讓你感到困惑 - 這是一個字符串值,不是參考。)
  2. baseValue通過執行GetValue(baseReference)來確定。由於baseReference不是參考,所以該方法簡單地返回參數值,即baseValue = baseReference

正如你所看到的,就像例1中,baseValue是原始字符串值'some string'。步驟3和4是等價於實例中的步驟3和4 1.

所以,兩者的標識參考str和字符串文字'some string'評價爲相同的值 - 的原始字符串值'some string' - 並使用該值作爲baseValue爲新的參考,然後用()調用。由於這個引用有一個基本的基本值,所以在我的答案的開頭定義的語義適用。

+0

啊哈!非常感謝你:) – 2011-12-20 21:12:50

+0

我也讀過,但如何與參考相關的字符串文字?什麼是引用,或者更確切地說,什麼是已解析的名稱綁定? – 2011-12-20 21:15:05

+0

'+ 1' - 我在找那個! – 2011-12-20 21:16:10

1

the reference文字轉換爲對象:

字符串(雙或單引號表示)和字符串 返回從字符串中調用非構造函數上下文(即沒有使用新關鍵字的 )是原始字符串。 JavaScript自動地將 轉換爲基本字符串和字符串對象,因此可以使用 字符串對象方法來處理基本字符串。

+0

這就如我所設想的那樣,但我仍然無法在ECMAScript規範中找到它。你知道這個行爲在那裏描述嗎? – 2011-12-20 21:06:05

相關問題