2013-04-07 54 views
2

有人可以在JavaScript中解釋這種行爲嗎?無法修改添加到Number.prototype的屬性

var a = 6; 
a.constructor.prototype.prop = 5; 
print(a.prop); 
a.prop = 4; 
print(a.prop); 

然後我ideone運行:

5 
5 

我明白a本身就是一個number,但其prorotype是object。但爲何存在這種差異?當然,這可能是多重編碼錯誤的根源。這被認爲是JavaScript的「邪惡部分」嗎?

回答

4

問題是a是一個原始值。不是一個對象。您只能將屬性分配給對象。不是原始值。

當您嘗試將屬性分配給原始值時,JavaScript會立即將其強制轉換爲對象。例如:

var x = true; // x is primitive 
x.y = false; // x is coerced to an object 
alert(x.y); // y is undefined 

在這裏看到演示:http://jsfiddle.net/UtYkA/

發生了什麼事的下聯是:

new Boolean(x).y = false; // x is not the same as new Boolean(x) 

因爲x被脅迫的對象和屬性y被添加到該對象沒有任何屬性已被添加到x本身。

對於所有基元 - JavaScript中的布爾值,數字和字符串也是如此。這就是爲什麼print(a.prop)總是打印5 - a是一個原始的,而不是一個對象。

當您嘗試訪問a.prop時,它會將a強制轉換爲對象,但不是每次都是相同的對象。因此,JavaScript的對待它,如下所示:

var a = 6; 
new Number(a).constructor.prototype.prop = 5; 
print(new Number(a).prop); 
new Number(a).prop = 4; // assigning prop to an object which is discarded 
print(new Number(a).prop); // accessing prop from an object which has no prop 

欲瞭解更多信息,請閱讀以下答案:https://stackoverflow.com/a/15705498/783743

+0

非常簡潔!謝謝。 'print((4).constructor.prototype ===(new Number(5))。constructor.prototype);'完全按照你的解釋輸出結果。 – 2013-04-07 07:48:28

+0

你會像在其他語言中一樣調用這個強制「拳擊」嗎? – ErikE 2013-04-07 08:04:40

+0

@ErikE - 不,強制和拳擊是兩個不同的概念。例如,在JavaScript中,「2」 - 1「等於」1「。這裏的字符串('「2」')被強制爲一個數字,然後從中減去'1'。在JavaScript中,根據上下文,一個值(無論是原始值還是參考值)可能會被強制(自動轉換)爲另一個值。例如,minus運算符需要兩個數字。類似地,點操作符期望左側的對象。另一方面,拳擊總是將原始值轉換爲引用,並且可能隱含或不隱含 - C#。 – 2013-04-07 09:57:51