2009-05-17 105 views
87

下面的兩個不同的代碼片段似乎等同於我:數組與對象有什麼區別?

var myArray = Array(); 
myArray['A'] = "Athens"; 
myArray['B'] = "Berlin"; 

var myObject = {'A': 'Athens', 'B':'Berlin'}; 

,因爲它們都具有相同的行爲,也typeof(myArray) == typeof(myObjects)(包括產量「對象」)。

這些變體之間有區別嗎?

回答

107

幾乎所有的JavaScript是一種對象,這樣你就可以「濫用」的Array對象通過它設置任意屬性。這should be considered harmful雖然。數組用於數字索引的數據 - 對於非數字鍵,使用Object。

這裏有一個更具體的例子,爲什麼非數字鍵不「適合」的Array:

var myArray = Array(); 
myArray['A'] = "Athens"; 
myArray['B'] = "Berlin"; 

alert(myArray.length); 

這將不顯示「2」,而是「0」 - 有效,沒有任何元素已經添加到數組中,只是添加到數組對象的一些新屬性。

+2

myArray.length返回數組中最後一個元素的數字索引/鍵,但不是實際元素數。 Array對象的屬性與數組值不同? – 2009-05-17 09:50:19

+1

我只是試圖說明Array對象的預期語義被濫用,如果你只是把它當作普通對象來對待。鏈接的文章做得更好:) – 2009-05-17 10:19:26

+5

下次有人說JavaScript是一種很好的開發語言時,我會向他展示這個示例。謝謝。 – 2014-04-19 08:04:49

-1

{} -notation只是語法糖使代碼更好;-)

JavaScript有許多相似的結構,如功能,施工,其中()函數僅僅是

var Func = new Function("<params>", "<code>"); 
的代名詞
+3

功能構造是**不**的功能文字的代名詞。文字是詞法作用域,而構造函數是全局的。 '{}'是文字對象表示法,'[]'是文字數組,我不確定你的答案是什麼。 – 2011-04-21 17:11:17

+0

另外,聲明的函數在任何代碼執行之前都可用,使用函數構造函數的賦值在創建它們的代碼執行之前不可用。 – RobG 2014-09-11 02:52:58

13

在JS數組中是對象,只是稍作修改(有幾個更多的功能)。

功能,如:

concat 
every 
filer 
forEach 
join 
indexOf 
lastIndexOf 
map 
pop 
push 
reverse 
shift 
slice 
some 
sort 
splice 
toSource 
toString 
unshift 
valueOf 
+0

儘管我不認爲列出的所有函數都內置在每個JS實現中,但您明白了。另一個區別將是不同的原型(這是由這些額外功能所暗示的)。 – Rashack 2009-05-17 09:26:40

5

JavaScript中的所有內容都是除原始類型之外的對象。

代碼

var myArray = Array(); 

var myObject = {'A': 'Athens', 'B':'Berlin'}; 

創建對象對象的實例創建Array對象的一個​​實例。

試試下面的代碼

alert(myArray.constructor) 
alert(myObject.constructor) 

所以你會看到不同的是在對象的構造函數的類型。

Array對象的實例將包含Array原型的所有屬性和方法。

4

我認爲,我對以前的回答太隱喻和隱晦。澄清如下。

Array,Boolean,Date,Function,Number,RegExp,String的一個實例是一個對象,但增強了特定於每種類型的方法和屬性。例如,數組具有預定義的length屬性,而通用對象則不具有。

javascript:alert([].length+'\n'+{}.length) 

顯示器

 
0 
undefined 

本質,則FF壁虎解釋器還區分陣列,並用顯着差異評估語言構造的通用對象之間。

javascript: 
    ra=[ "one", "two", "three"]; ra.a=4; 
    ob={0:"one", 1:"two", 2:"three"}; ob.a=4; 
    alert(
    ra   +"\n\n"+ 
    ob   +"\n\n"+ 
    ra.toSource() +"\n\n"+ 
    ra.a   +"\t .toSource() forgot me! \n\n"+ 
    ra.length  +"\t and my length! \n\n"+ 
    ob.toSource()); 
    ps=""; for(i in ra)ps+=i+" "; alert(ps); /* NB .length is missing! */ 
    ps=""; for(i in ob)ps+=i+" "; alert(ps); 

顯示

 
one,two,three 

[object Object] 

["one", "two", "three"] 

4 .toSource() forgot me! 

3 and my length! 

({0:"one", 1:"two", 2:"three", a:4}) 

0 1 2 a0 1 2 a和。

關於所有對象都是函數的語句:

這既不是語法上也不語義正確使用任意對象實例像123()"abc"()[](){}()obj()的函數,其中obj比其他任何類型因此任意對象INSTANCE不是Function。然而,給定一個對象obj,它的類型爲Array, Boolean, Date, ...obj是如何作爲Array, Boolean, Date, ...?什麼是Array, Boolean, Date, ...

javascript: 
    alert([Array, Boolean, Date, Function, 
       Number, Object, RegExp, String] . join('\n\n')); 

顯示器

function Array() { 
    [native code] 
} 

function Boolean() { 
    [native code] 
} 

function Date() { 
    [native code] 
} 

function Function() { 
    [native code] 
} 

function Number() { 
    [native code] 
} 

function Object() { 
    [native code] 
} 

function RegExp() { 
    [native code] 
} 

function String() { 
    [native code] 
} 

在每種情況下,毫不含糊,對象類型表現爲function定義,因此,所有對象都是函數的聲明! (我的意思是我故意掩蓋並模糊了對象實例與它的類型的區別!但是,這表明「你不能沒有其他實例」,Object和Function!Capitalization強調類型爲反對實例。)

兩者的功能和對象範似乎根本到編程和執行JS解釋低電平內置原語,如MathJSONtrue

javascript:alert([Math, JSON, true.toSource()].join("\n\n")); 

顯示

[object Math] 

[object JSON] 

(new Boolean(true)) 

在JavaScript中,對象爲中心的編程風格(OOP的開發時間 - 面向對象的編程風格 - 將「的」是我自己的雙關語!)流行起來,口譯員被類似的Java命名,以增強其可信度。函數式編程技術被歸入研究自動機,遞歸函數,形式語言等等的理論的更抽象和深奧的考試,並且因此不如可口。然而,這些正式考慮的優勢在Javascript中明顯體現出來,特別是在FF的Gecko引擎中實現(例如,.toSource())。


函數的對象定義特別令人滿意,因爲它被定義爲遞歸關係!使用它自己的定義來定義!

function Function() { [native code] }
並且由於功能是用於
function Object() { [native code] }對象相同的情緒成立。

大多數其他定義靜默終端價值。但是,eval()是一個特別強大的原語,因此字符串也可以嵌入任意功能。

再次注意,上面使用的白話模糊了對象類型和實例的區別。上array所有非數字指標被忽略使用JSON.stringify

1

一個實際的區別是:

var arr = []; 
var obj = {}; 

arr['name'] = 'John'; 
obj['name'] = 'John'; 

console.log(arr); // will output [name: "John"] 
console.log(obj); // will output {name: "John"} 

JSON.stringify(arr); // will return [] 
JSON.stringify(obj); // will return {"name":"John"}