最近我开始在firefox'中看到这个控制台
Object [ <6 empty slots>, false, <3 empty slots>, 1 more… ]
当我有像
这样的对象时{
6: false,
10: true
}
我只是想要一个可以访问的带有数字键的对象,但是我很担心,因为如果它跟踪空槽,那么这必然意味着浪费了一些内存?
我的关注是否有效,如果是,那么定义这样一个对象的正确方法是什么?
答案 0 :(得分:8)
这个问题可能是由Firefox'console.log
解释输入对象引起的。不知何故,它被评估为一个数组而不是一个简单的对象。 Chrome做得对。如果您仔细研究如何在Javascript中管理数组,可以找到以下内容:
数组不能使用字符串作为元素索引(如在关联数组中),但必须使用整数。使用括号表示法(或点表示法)通过非整数设置或访问不会从数组列表本身设置或检索元素,但会设置或访问与该数组的对象属性集合关联的变量。数组的对象属性和数组元素列表是分开的,并且数组的遍历和变异操作不能应用于这些命名属性。 src
更好地理解这一点是修补Array的length
属性。特别是当您使用[]
构建数组时。要向数组添加元素,我们必须使用.push(...)
。此函数使用length
属性(选中15.4.4.7 Array.prototype.push
)。简而言之(交互式示例位于底部)
const arr = []; // length = 0
arr.push('1stEl', '2ndEl', '3thEl'); // length = 3
// this isn't allowed, but you can do this
arr[7] = '7thEl'; // length = 8
您看到长度现在是8
而不是4
。索引3..6
是保留的,但未定义。以下是控制台输出。
[
"1stEl",
"2ndEl",
"3thEl",
undefined,
undefined,
undefined,
undefined,
"7thEl"
]
如果再次使用.push
方法,它会将新元素放在'7thEl'
元素之后(依此类推索引8)。
要检查此对象使用的密钥,我们可以在阵列上使用Object.keys()
。你会得到
[
"0",
"1",
"2",
"7"
]
您会看到数值用作键。就像你的对象一样,
{
6: false,
10: true
}
在此对象上使用Object.keys
可获得["6", "10"]
。它具有与上述类似的输出。因此来自firefox的console.log
已将您的对象解释为数组,从而将其显示为数组。为了正确显示数组,它在键0
处开始(逻辑上看,需要检查源代码)并在键array.length - 1
处结束。但索引0,1..5
和7..9
未“定义”。因此它导致了这个输出
Object [ <6 empty slots>, false, <3 empty slots>, 1 more… ]
我不确定我是否必须将此限定为Firefox的控制台API中的错误或故障...或者控制台输入(初始化变量时)已错误地读取了对象。
---实例 -
const a = new Array(3);
console.log('using "new Array(...)" reserves memory space: ' + a.length);
console.log('---');
// using brackets
const b = [];
console.log('but what with [] ? At initial, we have ' + b.length);
b.push('1stEl', '2ndEl', '3thEl');
console.log('After push(\'1stEl\', \'2ndEl\', \'3thEl\'), we have ' + b.length);
// add to random index
b[7] = '7thEl';
console.log('After b[7] = \'7thEl\', we have ' + b.length);
console.log('displaying gives ', b);
console.log('using Object.keys: ', Object.keys(b));
// adding again
b.push('newEl');
console.log('After b.push(\'newEl\'), we have ' + b.length);
// object
const obj = {
6: false,
10: true
};
console.log('obj defined as {6: false, 10: true }');
console.log('using Object.keys: ', Object.keys(obj));
console.log('obj: ', obj);
答案 1 :(得分:2)
Javascript使用稀疏数组。 &#34;由于数组的长度可以随时改变,并且数据可以存储在数组中的非连续位置,因此不能保证JavaScript数组密集;这取决于程序员如何选择使用它们。&#34; (source)
如果对象的类型为Array
,则使用的内存是引擎的实现细节。在您的情况下,对象是object
s,因此它只占用对象本身的内存,并存储属性名称和对属性值的引用。