2013-12-22 105 views
8

我想了解編寫m = Number()(導致typeof m評估爲"number")與m = new Number()(導致typeof m評估爲"object")之間的差異。Number()vs new Number()?

我會預料它是一個object無論哪種方式。我只是瞎搞,我增加了一個.helloWorld()方法將Number原型,我能夠訪問它m不管我用它實例哪種方法。

這裏有什麼區別?我在寫​​和new Number()時做了什麼不同?爲什麼一個是object而另一個是number

+0

執行一個構造而不'new'可以揍的'window'對象。 –

+0

本系列文章中的圖表爲我闡明瞭JS對象模型:http://howtonode.org/object-graphs-2。 –

+1

「[*當** Number **作爲函數調用而不是作爲構造函數調用時,它執行類型轉換。*](http://www.ecma-international.org/ecma-262/5.1/#sec -15.7.1)「vs.」[*當** Number **作爲** new **表達式的一部分被調用時,它是一個構造函數:它初始化新創建的對象。*](http:// www。 ecma-international.org/ecma-262/5.1/#sec-15.7.2)「 –

回答

4

​​本身返回一個數字原語。當您致電new Number()時,您會收到代表Numberrelevant ES5 spec)的對象的新實例。

在基元上調用屬性時,該基元會自動裝箱(如使用Java)到該對象的實例,這可讓您在objectnumber上調用helloWorld()

然而,試試這個;

var x = Number(5); 
x.bar = function (x) { alert(x); }; 
x.bar("hello"); 

var y = new Number(5); 
y.bar = function (x) { alert(x); }; 
y.bar("hello"); 

你會看到後者的作品,而前者沒有;在第一個中,number被自動裝箱到一個數字,並且bar方法被添加到它(對象)。當你調用x.bar()你正在創建一個新自動盒裝數值,bar不存在的。

在後者中,您將爲該Number實例添加一個bar方法,該實例的行爲與任何其他Object實例相似,因此它在對象的整個生命週期中都保持不變。

+0

對全局/本地/參數名稱使用相同的名稱通常是一個糟糕的主意;在一個例子中這樣做會增加混淆。我建議爲你的匿名函數使用不同於'x'的參數名稱。 – vol7ron

3

這只是它是如何實現的。這個特殊的構造函數在沒有new的情況下調用時會返回一個原始數字。當用new調用時,它返回對象包裝數字。

您可以訪問基元上的原型方法/屬性,因爲在幕後,JavaScript會將它們轉換爲對象,調用原型方法,然後丟棄對象副本。這允許你做這樣的事情:

var myString = "foo"; 
console.log(myString.length); //=> 3 
console.log(typeof myString); //=> "string" 

原始的目的副本得到兩線發,對象的length屬性被選中,然後將對象複製扔掉。 myString保持爲字符串原語。