How do arrays store empty values - JavaScript - javascript

Not too long ago, I discovered that arrays in JavaScript need not contain an ordered set of keys (0-x) to store values within it
and some numeric keys may not be defined (0-4 ... 6-x, where 5 is not defined).
And this creates semantically two types of arrays that are similar:
arrayA = [, ,] (partially-empty arrays or sparse arrays)
arrayB = [undefined, undefined] (filled arrays)
But recently, I was tinkering with JavaScript in the Google Chrome Developer Console and came across this:
Now the second array is like arrayA, and the third like arrayB as shown in the console.
But the first array ([...'🏃🏽‍♀️'])... what is it?
I opened up its directory and saw the elements that were defined as hole were undefined with their respective keys in the array.
I also ran a few types of JavaScript loops on the array:
for...in statement captures all elements, except the *hole*s.
for...of statement captures all elements, except the *hole*s and proceeds to throw an error that the iterator variable used is undefined i.e.:
for (var value of [...'🏃🏽‍♀️']) console.log(value);
// Throw 'ReferenceError' when loop is done.
Array.prototype.forEach method captures all elements, except the *hole*s.
do...while, for and while statements captures all elements, except the *hole*s.
Why does the console see those values as different from empty or undefined (as with arrayA and arrayB)?
The main question is: Is there implicitly another type of array and if so, is there anything to note about it?

The ... is known as spread syntax. Read more about it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
Emojis are made up of a variety of elements which the browser renders as a single emoji. Here's a quick article that expands on that. https://til.hashrocket.com/posts/2f488279a3-expand-emojis-with-the-spread-operator
By applying the spread syntax to an emoji, you can look at the individual emojis it's composed of.

Related

JavaScript Array `console.log` output behaviour

When we run a forEach() function on an array depending on the way the index & items are arranged dev tools returns different output. I'm wondering if anyone knows why this happens.
Please see the images below:
When I swap the variables over from item, index to index, item the output looks different.
I wonder what makes the variable output different and why.
According to MDN documentation regarding console.log here
This explains that the first parameter is handled either as an object or a string. Subsequent parameters are handled as objects.
I assume this forces the strings, from the second parameter onward, to print with quotes.
To read more about the chrome-console, visit this page
as here says
Syntax
console.log(obj1 [, obj2, ..., objN]);
console.log(msg [, subst1, ..., substN]);
Parameters
obj1 ... objN
A list of JavaScript objects to output. The string representations of each of these objects are appended together in the order listed and
output.
and when you write consoloe.log(item,index) it first write item and then index and vice versa

Typed arrays in JavaScript are not arrays

var a = Int32Array(10);
console.log(Array.isArray(a)); // prints false to the console (Firefox)
Is there a reason why a typed JavaScript array is not an array or is this a bug that needs to be reported?
No, typed arrays aren't arrays, it doesn't need reporting.
They're a very distinct set of objects with different functions. In the specification, they're described as objects which
present an array-like view of an underlying binary data buffer
A good reason not to confuse them : they don't even offer the functions you have on arrays, for example splice.
It also doesn't follow the spec of Array.isArray as it's not an "Array object" as can be verified by setting the value at an out of range index using the bracket notation and checking the length isn't changed.

Does anyone know how consistent `[1,,2]` only having two keys is?

I'm wondering if I can rely on the fact that [1,,2] only has two keys: 0 and 2, or if anyone happens to know if any JS engines will also give me a 1.
Every browser I've tested shows keys 0, 2, but I don't have older versions available at the moment, or an android phone, or ...
Reasoning:
I'm writing a custom timer library on top of requestAnimationFrame and so am returning cancelable ids based on internal array indices. I'm trying to figure out if simply delete ary[ix] is sufficient to be able to walk all of the object keys on the array without extra sanity checks.
You are covered if you are willing to assume that your code will be running on a conforming implementation of ECMAScript. From the spec:
Array elements may be elided at the beginning, middle or end of the
element list. Whenever a comma in the element list is not preceded
by an AssignmentExpression (i.e., a comma at the beginning or after
another comma), the missing array element contributes to the length of
the Array and increases the index of subsequent elements. Elided array
elements are not defined. If an element is elided at the end of an
array, that element does not contribute to the length of the Array.
[1,,3] will produce
[1, undefined, 3]
The length returned is 3.
Edit: to clarify, even though the value is present, a key is not returned.
Object.keys([1,,3]) returns ["0", "2"]
Edit 2: a great answer about checking if an array key exists.
Checking if a key exists in a JavaScript object?

JS object key sequence

Does javascript guarantees that the sequence of keys of an object gets preserved even if the new value is assigned to a key?
For example, if i have the following object
var Object = {
keyX: value1,
keyB: value2,
keyZ: value3
}
If i iterate through keys using for .. in, I get the proper sequence i.e. keyX, keyB, keyZ. and if I change the value of keyB, I am still getting the same sequence in iteration.
My question is, will the sequence remains the same always, or it might change in any case?
Well, it's quite clearly said in the doc (MDN):
A for...in loop iterates over the properties of an object in an
arbitrary order.
And this section of documentation gives more comprehensive explanation to this:
Although ECMAScript makes iteration order of objects
implementation-dependent, it may appear that all major browsers
support an iteration order based on the earliest added property coming
first (at least for properties not on the prototype). However, in the
case of Internet Explorer, when one uses delete on a property, some
confusing behavior results, preventing other browsers from using
simple objects like object literals as ordered associative arrays.
In Explorer, while the property value is indeed set to undefined, if
one later adds back a property with the same name, the property will
be iterated in its old position--not at the end of the iteration
sequence as one might expect after having deleted the property and
then added it back.

Can chrome be forced to iterate "string numeric" keys in the order they are stored

I seem to be having an interesting problem only in chrome (not IE, FF). Given the following object:
var myObj = {
"59" : "Hello",
"52" : "and",
"50" : "how",
"31" : "are",
"65" : "you"
};
Going over this object via a for loop spits out the contents in the following order:
for(var j in myObj) { document.write(myObj[j] +', '); }
are, how, and, hello, you
All the other major browser give it in 'proper' order. Chrome is treating the keys as integers instead of strings. The problem is I have a json data source I can't change, and I need to access the items in the order they're in the object.
Can anyone suggest a way to do this in Google Chrome?
When iterating over an object via for...in, the order of properties is not guaranteed. There is nothing you can do:
A for...in loop iterates over the properties of an object in an arbitrary order (see the delete operator for more on why one cannot depend on the seeming orderliness of iteration, at least in a cross-browser setting).
And from the delete page:
Although ECMAScript makes iteration order of objects implementation-dependent, it may appear that all major browsers support an iteration order based on the earliest added property coming first (at least for properties not on the prototype). However, in the case of Internet Explorer, when one uses delete on a property, some confusing behavior results, preventing other browsers from using simple objects like object literals as ordered associative arrays. In Explorer, while the property value is indeed set to undefined, if one later adds back a property with the same name, the property will be iterated in its old position--not at the end of the iteration sequence as one might expect after having deleted the property and then added it back.
So if you want to simulate an ordered associative array in a cross-browser environment, you are forced to either use two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc.
If you would like to know why it is like that, feel free to read the very long discussion in the V8 Issue Tracker "Wrong order in Object properties interation":
http://code.google.com/p/v8/issues/detail?id=164

Categories