admin管理员组文章数量:1201793
Lately I started seeing this in firefox' console
Object [ <6 empty slots>, false, <3 empty slots>, 1 more… ]
When I have an object like
{
6: false,
10: true
}
I simply want an object with numeric keys that I can access, but I am worried by this because if it keeps track of empty slots then this must mean that some memory is wasted?
Are my concerns valid and if yes what would be a correct way to define such an object?
Lately I started seeing this in firefox' console
Object [ <6 empty slots>, false, <3 empty slots>, 1 more… ]
When I have an object like
{
6: false,
10: true
}
I simply want an object with numeric keys that I can access, but I am worried by this because if it keeps track of empty slots then this must mean that some memory is wasted?
Are my concerns valid and if yes what would be a correct way to define such an object?
Share Improve this question asked Jun 13, 2017 at 6:27 php_nub_qqphp_nub_qq 16k22 gold badges81 silver badges148 bronze badges 2 |2 Answers
Reset to default 13The problem might be caused at how Firefox' console.log
has interpreted the input object. Somehow, it got evaluated as an array instead of a simple object. Chrome does it right. If you look deeper into how an array is managed in Javascript, you can find the following:
Arrays cannot use strings as element indexes (as in an associative array), but must use integers. Setting or accessing via non-integers using bracket notation (or dot notation) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array's object property collection. The array's object properties and list of array elements are separate, and the array's traversal and mutation operations cannot be applied to these named properties. src
A better comprehending for this is to tinker with Array's length
property. Especially when you have constructed your array by using []
. To add elements to the array, we have to use .push(...)
. This function uses the length
property (check 15.4.4.7 Array.prototype.push
). So in short (interactive example is at the bottom)
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
You see that the length is now 8
and not 4
. The indices 3..6
are reserved, but undefined. Here below is a console output.
[
"1stEl",
"2ndEl",
"3thEl",
undefined,
undefined,
undefined,
undefined,
"7thEl"
]
If you use a .push
method again, it will place the new element after the '7thEl'
element (so on index 8).
To check the keys that is used by this object, we can use Object.keys()
on the array. You will get
[
"0",
"1",
"2",
"7"
]
You see that numeric values are used as keys. Like your object, which is
{
6: false,
10: true
}
Using Object.keys
on this object gives ["6", "10"]
. It has a similar output as the above. So the console.log
from firefox has interpret your object as an array, thus displaying it as an array. In order to display the array correctly, it starts (logically seen, need to check the source code yet) at key 0
and ends at key array.length - 1
. But the indexes 0,1..5
and 7..9
aren't "defined". Thus it leads to this output
Object [ <6 empty slots>, false, <3 empty slots>, 1 more… ]
I'm not sure if I have to qualify this as a bug or glitch at Firefox's console API... Or that the console input (when initializing a variable) has read the object incorrectly.
--- live example --
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);
Javascript uses sparse arrays. "Since an array's length can change at any time, and data can be stored at non-contiguous locations in the array, JavaScript arrays are not guaranteed to be dense; this depends on how the programmer chooses to use them." (source)
If the objects are of type Array
, then the memory used is an implementation detail of the engine. In your case, the objects are object
s, so it only takes the memory for the object itself, and to store the property names and references to property values.
本文标签: Empty slots in JavaScript objectsStack Overflow
版权声明:本文标题:Empty slots in JavaScript objects? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738607611a2102442.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
[{6:false, 10:true}]
the condensed view outputsArray [ Object[11] ]
– Kaiido Commented Jun 13, 2017 at 6:38