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?
Answer: Use the array_push() Function You can simply use the array_push() function to add new elements or values to an empty PHP array.
Each of the bracket pairs is a slot(element) in the array, and you can put information into each one of them. It is almost like having a group of variables side by side.
To check if an array is empty or not, you can use the . length property. The length property sets or returns the number of elements in an array. By knowing the number of elements in the array, you can tell if it is empty or not. An empty array will have 0 elements inside of it.
1 containing nothing. 2 without inhabitants; vacant or unoccupied. 3 carrying no load, passengers, etc. 4 without purpose, substance, or value.
The 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With