2012-05-07 39 views
3

考慮以下幾點:Math.round是不是構造

x = function() {} 
p = new x() 
console.log(p) // ok 

Math.z = function() {} 
p = new Math.z() 
console.log(p) // ok 

p = new Math.round() 
console.log(p) // TypeError: function round() { [native code] } is not a constructor 

所以我可以用new用我自己的功能,但不能用Math.round。是什麼讓它如此特別?這是記錄在某處嗎?

回答

8

沒什麼特別之處Math.round可以複製在自己的函數此行爲:

MyClass = function(){}; 
MyClass.round = function(x){ 
    if(this instanceof MyClass.round) 
     throw 'TypeError: MyClass.round is not a constructor'; 
    return Math.round(x); 
} 

console.log(MyClass.round(0.5)); // 1 
new MyClass.round(); // 'TypeError: MyClass.round is not a constructor' 

事實上,你可以使用一個類似的模式,使new關鍵字可選的上您的分類:

function MyClass(){ 
    if(!(this instanceof MyClass)) // If not using new 
     return new MyClass();  // Create a new instance and return it 

    // Do normal constructor stuff 
    this.x = 5; 
} 

(new MyClass()).x === MyClass().x; 

至於爲什麼new不帶內置的功能和方法的工作,這是由設計,並記錄在案:那是本節中描述的內置函數

無不是建設單位應當落實[建設]內部方法,除非在特定功能的描述中另有規定。 - http://es5.github.com/#x15

+0

謝謝,但這並不能解釋爲什麼'new foo.bar'工作並且'new Math.round'沒有。 – georg

+0

@ thg435因爲'Math.round'被設計爲失敗。就像我的函數MyClass.round被設計爲失敗。除非'foo.bar'專門設計爲在這種情況下失敗,否則不會。 – Paulpro

+0

你有沒有任何證據證明「Math.round」實際上是這樣設計的? – georg

1

數學是一個類,所以你可以從中創建一個對象。 Math.round是Math的一種方法。您不能從方法創建對象。

+0

嗯,我不這麼認爲。對於初學者來說,JavaScript中沒有「class」這樣的東西。 – georg

+0

是真實的,但您可以使用函數模擬一個類 –

2

這是一種方法,這就是爲什麼你不能把new放在它之前。

PS:

new alert()  //TypeError: Illegal invocation 
new console.log() //TypeError: Illegal invocation 
new function(){} //OK 
+0

您可以使用'new'與您自己的方法,例如, 'new foo.bar()'。 – georg