2011-01-19 13 views
2

屬性(鍵)可以使用點符號以及方括號來訪問和設置。任何建議時使用點原型語法在JavaScript中,創建屬性時,哪種方法是正確的或更好的語法?

var myObj = {}; 
myObj.myProp1 = 'value1'; //works, an expando property 
myObj[myProp2] = 'value2'; // FAILS, myProp2 is undefined 
myObj["myProp2"] = 'value2'; // works, an expando property 
myObj[2010]= 'value'; //note the key is number, still works, an expando property?? 
myObj.2010 = 'value'; // FAILS. to use dot notation, key must be a string 

myObj.prototype.myProp3 = 'value3' // whats the advantage? 
+1

`FOO。 [...]`是一個語法錯誤 - 你可能意指`foo [ – Christoph 2011-01-19 12:09:31

+1

其實``foo ['...']`。 `foo [「...」]`也是。 – Thai 2011-01-19 12:29:03

回答

4

當使用點語法中,屬性格式名稱是IDENTIFER:

var myObj = {}; 
myObj.myProp1 = "value1"; 
myObj.myProp2 = "value2"; 

作爲屬性名必須遵循標識符命名規則,例如它可以不以數字開頭。

當使用括號語法,屬性名是一個字符串:

var myObj = {}; 
myObj["myProp1"] = "value1"; 
myObj["myProp2"] = "value2"; 

是什麼在括號中使用可以是可變的,或任何類型的表達,其導致的字符串:

var myObj = {}; 
var prop1 = "myProp1"; 
myObj[prop1] = "value1"; 
myObj["myProp" + 2] = "value2"; 

如果使用數字作爲屬性名稱,它會自動轉換爲字符串,所以這些有同樣的結果:

myObj[2010] = "value"; 
myObj["2010"] = "value"; 

您還可以使用對象文本來設定值:

var myObj = { myProp1: "value1", myProp2: "value2" }; 

(注意:{}也是一個對象文本,只有無屬性)

使用對象的原型是,如果只是有用你已經命名了對象類型(或者將一個原型分配給對象)。當使用對象字面值創建對象時,每個對象都有自己的原型,因此將任何內容放入原型中與將其放入對象中的效果相同。

1

屬性加成應該是myObj.myPropmyObj["myProp"]。這是理想的情況下,並在JavaScript中使用一個很好的做法。

1
var myObj = function() { 

}; 
myObj.prototype.myProp3 = 'value3' // whats the advantage? 

如果你想使用myObj作爲一個構造來創建多個對象,應該使用這個。即。

var obj1 = new myObj(); 

然後OBJ1也將獲得myProp3財產

編輯:編輯上面的例子。要使用myObj作爲構造函數,應將其聲明爲函數

1

對於您的情況,應使用myObj.prototype.myProp3 = 'value3'而不是,因爲對象文字沒有原型。他們這樣做,但他們沒有prototype屬性(你會看到myObj.prototype未定義)。

原型在函數上使用,以使用關鍵字new設置從該函數構造的所有對象的默認屬性。這並不意味着用於將屬性分配給單個對象。

1

對我來說,這取決於我將如何使用該對象。

如果我要像使用關聯數組,散列圖或點句法不可能的那樣使用它,我使用[]

但是,如果我將它們視爲對象,則使用.語法。

1

基本上,通過「。」訪問對象的屬性沒有區別。語法或通過鍵。

var obj = new function(){this.x = "value";} 
alert(obj.x === obj['x']); //it will output true 

有時您不能使用「。」 ,因爲你要訪問的屬性的名稱是不是有效的變量名稱(如你與你的數字鍵指出):

var obj = new function(){this['my-value'] = "my value";} 
alert(obj['my-value']); // it will output "my value" 
alert(obj.my-value); // it will trigger an exception , because the javascript 
//interpretor interprets "obj.my-value" as the 
//property "my" of obj minus the variable "value" 

最大的區別就是瀏覽器處理你的語法的方式。正如你可以看到here,我的一個朋友做了一些測試,看起來Chrome和IE使用點語法工作得更快,而Firefox和Safari更關注關鍵語法。
總之,幾乎每次都可以使用其中任何一個,儘管存在「。」的情況。有點「毫無準備」。

關於原型語法,當您定義一個對象時,您可以將成員附加到每個實例,但您也可以將成員附加到該對象的原型,這意味着無論何時創建了已定義類型的新對象,它會自動從它的原型繼承該成員。我認爲這是更好地理解一個例子:

 
function Point(x,y){this.x = x;this.y = y;} 
Point.prototype.toString = function(){ 
    return "I am a point with my x coord at "+this.x+" and my y coord at "+this.y; 
} 

function Point2(x,y){ 
    this.x = x; 
    this.y = y; 
    this.toString = function(){ 
    return "I'm a point too.I'm at x:"+this.x+", y:"+this.y; 
    }; 
} 

當你創建一個new Point2,這是toString方法的實例方法和JavaScript解釋器這種方法分配內存。
當你創建一個'新點'時,它的toString方法將被鏈接在它的原型屬性上。這意味着沒有內存分配給該方法。

 
var p = [], p2 = []; 
for(var i = 0; i < 100000000; i++) 
    { 
    p.push(new Point(0,0)); 
    p2.push(new Point2(0,0)); 
    } 

如果你測試,你會看到這兩個對象都致力於完美,但你的Point2對象將採取更多的內存耗盡你的系統。這是爲什麼?
問題是,當你調用new Point()toString()方法時,該對象意識到它沒有名爲「toString」的成員,並且它開始搜索它的原型鏈並返回找到的'toString'成員在對象的聲明中。
在上面的例子中,所有的p的項目都會將他們的toString方法指向原型中提到的方法,而p2的所有項目都將指向它們的方法的每個副本。
此外,如果你以後想修改toString方法,否則很容易修改它所有的Point實例:
Point.prototype.toString = function(){return "I'm a smarter point";}; 之後,的new Point每個實例將返回「我是一個聰明點」當你把它叫做toString的方法。
如果您嘗試修改Point2實例,則會更困難。你會發現,Point2.toString = function(){return "I'm a dumber point";}不會按預期工作,你必須手動更改方法爲每個實例:

 
for(var i in p2) 
    p2[i].toString = function(){return "I'm a dumber point";}; 

我會讓你決定哪種方法比較好:P

相關問題