2013-12-19 74 views
5

這已經變得更多的JavaScript的工作,而不是一個實際的問題要解決的思考。在一份聲明中像自動javascript類型的強制

var str = 9 + " some words here"; 

的情況下得到的STR VAR將包含值「9一些話在這裏」。我的問題是JavaScript使用什麼函數將Number對象'9'自動強制爲一個字符串與字符串對象「這裏有些字」串聯,並且此功能是可更改/可覆蓋的。

這從我需要在頁面上輸出一個前面的0的單個數字開始。這是很容易的與Number對象

Number.prototype.SpecialFormat = function() { 
    if(this < 10) { 
    return "0" + this; 
    } 
    else { 
    return this.toString(); 
    } 
}; 

上快速原型函數來完成並配有簡單的(9).SpecialFormat() + " words here";

調用它,但是讓我知道如果我能覆蓋上有一個號碼的ToString函數

Number.prototype.toString = function() { 
    if(this < 10) { 
    return "0" + this; 
    } 
    else { 
    return this; 
    } 
}; 

,只是讓JavaScript的自動轉換處理它對於我來說,這樣我就可以使用標準的9 + " words here";以「這裏09字」得到同樣的結果。這不只是隱含的工作,我不得不最終添加.toString到9 (9).toString() + " words here"(它進一步看,會導致一些無限循環)。

那麼有沒有辦法來重寫JavaScript本機類型的內置功能?

*注:我意識到這可能是一個 '最糟糕的想法永遠'

+3

見[加法運算符(http://www.ecma-international.org/ecma-262/5.1/#sec-11.6 .1)(步驟7)以及[ToString](http://www.ecma-international.org/ecma-262/5.1/#sec-9.8)和「[ToString應用於數字類型](http ://www.ecma-international.org/ecma-262/5.1/#sec-9.8.1)」。看起來抽象操作'ToString(number)'從來沒有使用'Number.prototype.toString'(事實上,這是另一種方式)。 – apsillers

+0

我想這就是爲什麼當我在toString原型中使用String(this)時出現「超出最大調用堆棧大小」錯誤的原因。 –

+0

我假設在這種情況下,JavaScript的構造方式與其他面嚮對象語言的構造方式不同,您可以重寫應用於對象的運算符。在我看來,字符串連接是由解釋器內部完成的,忽略了所有重寫的方法。 – VisioN

回答

3

addition operator強求它的參數字符串步驟7:

  • 如果Type(lprim)爲String或類型(rprim)是字符串,則
    • 返回串聯ToString(lprim)後跟ToString(rprim)的字符串

ToString operation有編號的特殊規則,在 「ToString Applied to the Number Type」 詳細說明。

看起來,抽象操作ToString(number)從未使用過Number.prototype.toString。事實上,ti是相反的:default Number.prototype.toString function採用了抽象的數字ToString算法。因此,無法在ECMAScript 5中的類型強制轉換過程中重寫數字串的默認行爲,因爲無法更改語言定義的ToString操作。

的ToString 強迫對象爲字符串時使用目標的toString方法,而不是原始的編號值。

3

(不是嚴格意義上的答案,但我需要一些空間)

要非常小心的強制類型轉換,結合原始類型與它們的目的同行尤其是因爲:

var n = 9; 
typeof n; // "number" 
n instanceof Number; // false!! 

n = new Number(9); 
n instanceof Number; // true, oh thank God 
typeof n; // "object" what!! 

而且, toString on Number does not actually work:

Number.prototype.toString = function() { return "foo" + this; }; 
var n = new Number(9); 
"" + n; // "9", not "foo9" 

避免這種混亂的方法是通過具有:

var ns = { 
    number: { 
     specialFormat: function() /* .. */ } 
    } 
} 

ns.number.specialFormat(9); // "09" 
+0

'n =數字(9);'在第一個代碼塊中應該是'n = new Number(9);'。否則,您只需調用Number函數即可將該參數轉換爲數字原語,而原始數字原來就是這樣。因此,它後面的兩行將與之前的兩行相同。 – Sam