JavaScript对象中的空插槽?

时间:2017-06-13 06:27:36

标签: javascript

最近我开始在firefox'中看到这个控制台

Object [ <6 empty slots>, false, <3 empty slots>, 1 more… ]

当我有像

这样的对象时
{
  6: false,
  10: true
}

我只是想要一个可以访问的带有数字键的对象,但是我很担心,因为如果它跟踪空槽,那么这必然意味着浪费了一些内存?

我的关注是否有效,如果是,那么定义这样一个对象的正确方法是什么?

2 个答案:

答案 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..57..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,因此它只占用对象本身的内存,并存储属性名称和对属性值的引用。