鍍金池/ 問答/PHP  網(wǎng)絡(luò)安全  HTML/ 為什么js的"關(guān)聯(lián)數(shù)組"不能轉(zhuǎn)成json字符串而對象可以?

為什么js的"關(guān)聯(lián)數(shù)組"不能轉(zhuǎn)成json字符串而對象可以?

定義這么一個js的“關(guān)聯(lián)數(shù)組”:

var arr = new Array();
    arr['school'] = 1;
    arr['team'] = 2;
    alert(JSON.stringify(arr));

得到的結(jié)果如圖:
圖片描述

為什么會這樣?實在不知道為什么了,但是通過:

alert(arr.school);

這種方法可以取到值,這樣看是存在的,但是好像又不存在,實在搞不懂
用對象的方式就正常轉(zhuǎn)換:

var obj = {
    school: 1,
    team : 2
}
alert(JSON.stringify(obj));

如果說js不支持這種關(guān)聯(lián)數(shù)組的形式但為什么可以取值呢?能取到值但為什么轉(zhuǎn)成json字符串就什么也沒有了呢?

回答
編輯回答
初心

一句話,你的 arr 是有兩個屬性的空數(shù)組,數(shù)組轉(zhuǎn)字符串當(dāng)然是展示數(shù)組的內(nèi)容,不會去遍歷數(shù)組的屬性!下面解釋:

js不支持這種關(guān)聯(lián)數(shù)組的形式但為什么可以取值呢?

因為數(shù)組本身也是對象,特殊的對象,

var arr = new Array();
    arr['school'] = 1;
    arr['team'] = 2;

從對象的角度來看,你只是給 arr 對象增加了兩個屬性,那么你取值,實際上是讀取屬性,當(dāng)然是可以取到的的;你給 arr 增加值了么?沒有!這個地方,arr 的 length 還是 0 ,也就是說,arr 還是 [] 空數(shù)組,那么你用 JSON.stringify() 顯示的當(dāng)然是 []

clipboard.png

能取到值但為什么轉(zhuǎn)成json字符串就什么也沒有了呢?

能取到值是因為你取的是屬性,數(shù)組作為對象,當(dāng)然可以設(shè)置讀取屬性;
轉(zhuǎn)JSON什么都沒有,因為 arr 是空數(shù)組呀,所以取到的值肯定是 [];


引申,其實數(shù)組作為特殊的對象,他的 index,本身也是他的屬性,計算在length里面,你設(shè)置的 school,team 也是屬性,不算在length里,通常遍歷的時候,都是按照 index 遍歷的,屬性不遍歷,如果你設(shè)置 index 的屬性,默認(rèn)就是設(shè)置了數(shù)組中的項了,比如你上面的代碼改下,就是不同的結(jié)果:

clipboard.png

2018年5月2日 16:14
編輯回答
蟲児飛

其實這個我感覺不算錯只能說不符合規(guī)范
Array繼承自Object所以可以以對象的形式操作 以對象形式設(shè)置的值也可以通過for...in遍歷出
只不過是JSON.stringify遍歷數(shù)組的時候應(yīng)該做了判斷用for循環(huán)遍歷下標(biāo)的方式
關(guān)于可枚舉和可迭代在MDN,for...of中有下面代碼

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = 'hello';

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs 0, 1, 2, "foo"
  }
}

for (let i of iterable) {
  console.log(i); // logs 3, 5, 7
}
2017年4月8日 12:10
編輯回答
笑忘初

因為JSON.stringify處理數(shù)組對象的時候不是枚舉而是遍歷,就是按照 0length - 1 的順序處理,而處理{}對象的時候,是用枚舉把對象的可枚舉屬性都處理一次。

就是

for(var i = 0; i < arr.length; i++) {}

for(var i in obj) {}

的區(qū)別


詳細(xì)可以看看MDN上關(guān)于JSON 的 Polyfill
序列化數(shù)組的時候是這樣操作的

// ...
else if (isArray(value)) {
    var res = '[';
    for (var i = 0; i < value.length; i++)
        res += (i ? ', ' : '') + stringify(value[i]);
// ...
2017年8月14日 03:16
編輯回答
半心人

數(shù)組對象的迭代器以數(shù)字型下標(biāo)為key來遍歷對象

2018年4月16日 19:42