Are arrays objects in JavaScript? [duplicate] - javascript

This question already has answers here:
Are Javascript arrays primitives? Strings? Objects?
(7 answers)
Closed 3 years ago.
I have had discussions with seasoned programmers who do not think arrays are objects; they think that objects and arrays are of separate types of the data structure category. But, as far as I understand, objects and arrays are of the same type.
If you were to use the unary typeof operator to evaluate a binding storing an array, the JavaScript interpreter will return the string "object." Moreover, you can use the Object.keys() method on a binding containing an array to get the property names of the array object.
When studying programming, I see authors use the phrase "objects and arrays," as if these were separate entities, which adds to the confusion. I go to W3Schools, and in the section "Data Types," they list arrays and objects as if they are not of the same data type.
As far as I understand it, objects and arrays are the same, except array objects are structured different than objects delimited by braces. Perhaps I'm missing something and can be enlightened.
Are arrays objects? If so, shouldn't they be listed as the same type, and shouldn't the phrase be "arrays and other objects"? If not, why not?
(Edit: I know the question of if objects and arrays are the same has been asked, but I was also asking if there should be a change in how arrays and objects are discussed, so people don't think that arrays are not objects, since programming is not the easiest subject to digest.)

Arrays are indeed a type of object.
console.log([] instanceof Object);
I go to W3Schools, and in the section "Data Types," they list arrays and objects as if they are not of the same data type
W3Schools is not a particularly trustworthy source. That said, when discussing organization of data, it's pretty common to talk about arrays (an ordered collection of values) as distinct from objects (a usually-unordered collection of key-value pairs), despite the fact that one is a subtype of the other, because the fact that arrays inherit from Object.prototype often isn't something one needs to consider when organizing / sorting through data.
If one tries to use any of the Object methods on an array, it's certainly essential to remember that Array inherits from Object, but usually that's not necessary - often, one will be only be using array methods instead (like forEach, find, includes, etc).

Related

Is an array in JavaScript a pointers array? [duplicate]

This question already has answers here:
Are JavaScript Arrays actually implemented as arrays?
(2 answers)
How are JavaScript arrays implemented?
(8 answers)
Closed 2 years ago.
I am new to JavaScript and lately, I found out that arrays in JavaScript are like lists in Java and that they can contain different types of variables.
My question is if in JavaScript an array are made of pointers? How is it possible to have different types in the same array, because we must define the array size before we assign the variables?
I have tried to find some information on Google, but all I have found are examples on arrays ):
You do not have to define the array size before you assign the variables. You can go like:
let array = [];
array.push(12);
array.push("asd");
array.push({data:5});
array.forEach(element => {
console.log(element);
});
Also I think you should not think about pointers with such a high level language. The better way is to look at variables like 'primitives' and 'objects'. Here is a good read about it:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
High level languages, and in particular scripting languages, tend to reference most things with pointers, and they make pointer access transparent. Javascript does this also. Most everything, even primitives like numbers and strings, are objects. Objects in javascript have properties that store things. Those properties are essentially pointers, in that they are references to other objects. Arrays are implemented in the same way, and are in fact objects with numeric properties (and a few utility methods a standard object doesn't have, such as .length, .push(), .map(), etc.). Arrays don't hav a fixed size anymore than objects do. So everything in javascript is stored in these object "buckets" that can store anything in their properties (although you can seal objects, like numbers and strings, so that they don't accidentally change).
Languages with fixed data types (C like languages for instance) implement things with fixed data structures, and the exact size is easily calculable and known. When you declare a variable, the compiler uses the type of that variable to reserve some space in memory. Javascript handles all that for you and doesn't assume anything is a fixed size, because it can't. The size of javascript objects can change at any time.
In C-Like languages, when you ask for an array, you are asking for a block of a specific size. The compiler needs to know how big that is so that it can determine where in memory to put everything, and it can use the type of objects in the array to easily calculate that. Interpreted languages use pointers behind the scenes to keep track of where everything is stored, because they can't assume it will always be in the same place, like a compiled program can. (This is somewhat of a simplification and there are caveats to this of course).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
JavaScript is a loosely typed language, Therefore there is noting stoping you from having different types in javascript array. but I would strongly avoid structuring your data that way without static type-checking (Typescript)
const test = ['test', {test:'test'}, 1, true]

JavaScript Objects built on arrays [duplicate]

This question already has answers here:
Why can I add named properties to an array as if it were an object?
(8 answers)
Difference between array and object in javascript? or Array Vs Object
(4 answers)
Associative array versus object in JavaScript
(7 answers)
Closed 4 years ago.
From my readings, in JavaScript:
Objects = Hash Tables, which are build on Arrays. However, it is commonly said that Arrays are Objects in JS. How are these two concepts reconciled?
Objects are not built on arrays. Objects have their own optimizations.
In general:
Objects are for "structs", structures of predictable "shape" and keys known in advance (even though they can be used with dynamic keys, you should use Maps for that. See below).
Arrays are for lists (and queues, and stacks), structures where the keys are numbers, or where the order of elements matters. Arrays are "special" objects, not the other way around. (You can put string-based properties on an array, just like any object. Please don't do that though).
Maps are for hash tables/dictionaries, structures where the keys are dynamic and not known in advance.

How are Javascript's sparse arrays constructed? What is placed in each index?

I know this question has no practical usage, but I have read many different definitions of what sparse arrays are and I was wondering what the exact low level implementation of how these dynamic arrays are created.
Are sparse arrays an array of pointers? Or is it like an array of some kind of Struct node? Or is it some generic large space that can be filled with something small like a Char, or something big like a float?
If the array is only slightly sparse, the backing array is contiguous where hole indices have the the_hole value. The the_hole value is converted to undefined when dereferenced by the user. Indices with the the_hole value are also not reported as existing in the array by methods like Object.keys.
If the array is more sparse, it's simply a hash table with numbers as keys.
Unlike what is said in the comments, arrays are always assumed to be non-sparse and only converted to hash tables as a last resort rather than the other way around. That happens when you do something like define a custom property descriptor for an array index (never ever do that) or make the array too sparse.

Is there a specific reason why javascript has no isEqual() native function to compare Objects?

The object1 == object2 operation checks to see if the references are the same.
A lot of times we want to check if the objects structure (properties, values and even methods) are the same. We have to implement a isEqual() function for ourselves or use an external library.
Why isn't it just added to the javascript ECMA standard, like JSON.stringify() was?
Is there a specific reason?
For what I can gather, this hasn't been implemented because objects can have very different structures and only in very simple object structures consisting of name:value like obj = {name:"value",age="anotherValue"} the isEqual(obj1,obj2) would be useful.
Although I think it should be implemented nevertheless.
Most probably because there is no obvious way to determine what exactly makes two objects equal.
For example, you could check that they have the same property names with the same values. However,
These values can be objects, should their equality be loosely checked recursively? Then, what should be done with cyclic references?
Should only enumerable properties be checked, or all of them?
Should only string properties be checked, or also symbols?
Should only properties be checked, or also internal slots?
If not all internal slots are checked, which ones? For example, should the [[Prototype]] values in ordinary objects be compared, or maybe call the [[GetPrototypeOf]] method? Should all function internal slots be compared, or otherwise how would you determine function equality?
Should only the property values be compared, or also the configurability, writability and enumerability?
What about accessor properties? Should getters be called and compare the returned values, or compare the getters and setters themselves?
What about proxy objects, which may return a different set of properties each time you ask them?
There is no best answer to these questions. For each person, object equality might mean different things. So they can write a function which checks exactly what they want.

Object vs Arrays in Javascript is as Python's Dictionaries vs Lists?

I know in python I can use lists in order to make fast sortings and dictionaries in order to search things faster (because immutable objects can be hashed). Is that the same for javascript too? I haven't seen anything about the performance of datatypes in javascript after much search.
Yes. "Object vs Arrays in Javascript is as Python's Dictionaries vs Lists".
Performance pros and cons are also the same. With lists being more efficient if numeric indexes are appropriate to the task and dictionaries being more efficient for long lists that must be accessed by a string.
var dict = {};
dict['apple'] = "a sweet edible fruit";
dict['boy'] = "a young male human";
var list = [];
list.push("apples");
list.push("oranges");
list.push("pears");
I have been looking for some bibliography and other sources that could answer this question. I Know that this isn't the best answer, but let me try an answer that involve some concepts that lend us to discuss this topic.
Javascript and inheritance
Although the it could suggest that arrays and objects in javascript are like lists and dictionaries, they are different because each language are written in different ways, with different underlying philosophies, concepts and purposes.
In the case of Javascript, it seems that both Arryas and Objects are more like hash tables. Contrary to the intuition, Arrays are just an other type of built in object of javascript. In fact, as they say in the ECMAScript Specification 6.1.7
The Object Type
An Object is logically a collection of properties. Each property is
either a data property, or an accessor property:
A data property associates a key value with an ECMAScript language
value and a set of Boolean attributes. An accessor property associates
a key value with one or two accessor functions, and a set of Boolean
attributes. The accessor functions are used to store or retrieve an
ECMAScript language value that is associated with the property.
Properties are identified using key values. A property key value is
either an ECMAScript String value or a Symbol value. All String and
Symbol values, including the empty string, are valid as property keys.
A property name is a property key that is a String value.
An integer index is a String-valued property key that is a canonical
numeric String (see 7.1.16) and whose numeric value is either +0 or a
positive integer ≤ 253 - 1. An array index is an integer index whose
numeric value i is in the range +0 ≤ i < 232 - 1.
Property keys are used to access properties and their values. There
are two kinds of access for properties: get and set, corresponding to
value retrieval and assignment, respectively. The properties
accessible via get and set access includes both own properties that
are a direct part of an object and inherited properties which are
provided by another associated object via a property inheritance
relationship. Inherited properties may be either own or inherited
properties of the associated object. Each own property of an object
must each have a key value that is distinct from the key values of the
other own properties of that object.
And,about the arrays, it specifies:
22.1Array Objects
Array objects are exotic objects that give special treatment to a certain class of property names.
Following the logic above, and as it says in the specification, the language was thinked in such way that all types in javascript extends a global object, and then new methods and properties are added to have differents behaivors.
Memory Management
There are a gap between the language specifications and how they must be implemented in an actual runtime enviroment. Altought each implementation has its own logics, it seems that most of them has similarities.
As This Article Explains:
Most JavaScript interpreters use dictionary-like structures (hash
function based) to store the location of object property values in the
memory. This structure makes retrieving the value of a property in
JavaScript more computationally expensive than it would be in a
non-dynamic programming language like Java or C#. In Java, all of the
object properties are determined by a fixed object layout before
compilation and cannot be dynamically added or removed at runtime
(well, C# has the dynamic type which is another topic). As a result,
the values of properties (or pointers to those properties) can be
stored as a continuous buffer in the memory with a fixed-offset
between each. The length of an offset can easily be determined based
on the property type, whereas this is not possible in JavaScript where
a property type can change during runtime.
As this make javascript kind of ineffitient, the engineers had to came with some clever workarounds in order to solve this problem. Following this other article:
If you access a property, e.g. object.y, the JavaScript engine looks
in the JSObject for the key 'y', then loads the corresponding property
attributes, and finally returns the [[Value]].
But where are these property attributes stored in memory? Should we
store them as part of the JSObject? If we assume that we’ll be seeing
more objects with this shape later, then it’s wasteful to store the
full dictionary containing the property names and attributes on the
JSObject itself, as the property names are repeated for all objects
with the same shape. That’s a lot of duplication and unnecessarily
memory usage. As an optimization, engines store the Shape of the
object separately.
This Shape contains all the property names and the attributes, except
for their [[Value]]s. Instead the Shape contains the offset of the
values inside of the JSObject, so that the JavaScript engine knows
where to find the values. Every JSObject with this same shape points
to exactly this Shape instance. Now every JSObject only has to store
the values that are unique to this object.
The benefit becomes clear when we have multiple objects. No matter how
many objects there are, as long as they have the same shape, we only
have to store the shape and property information once!
All JavaScript engines use shapes as an optimization, but they don’t
all call them shapes:
Academic papers call them Hidden Classes (confusing w.r.t. JavaScript classes)
V8 calls them Maps (confusing w.r.t. JavaScript Maps)
Chakra calls them Types (confusing w.r.t. JavaScript’s dynamic types and typeof)
JavaScriptCore calls them Structures
*SpiderMonkey calls them Shapes
Python
Arrays
Python uses a different aproach for the implementation of lists, it seems that lists are more like some dynamics arrays than an actual array that you could find in C, But they are sill are focussed on saving spaces of time and complexity in a runtime. As this FAQ cited form the PyDocs says:
Python’s list objects are really variable-length arrays, not
Lisp-style linked lists. The implementation uses a contiguous array of
references to other objects, and keeps a pointer to this array and the
array’s length in a list head structure.
This makes indexing a list (L[i]) an operation whose cost is
independent of the size of the list or the value of the index.
When items are appended or inserted, the array of references is
resized. Some cleverness is applied to improve the performance of
appending items repeatedly; when the array must be grown, some extra
space is allocated so the next few times don’t require an actual
resize.
Like javascript, Python's lists are not required to be homogeneous, so they are not an actual implementation of other "strong typed" data structures that does have to contain only the same entities such as integers, strings, etc.
Same as javascript, the specifications of the language the actual implementation are two separate things. Depending on if you are using Cpython, Jython, IronPython, etc, the memory management and the actual functions that runs behind the scenes will be making diferent things in the process of interpreting python to machine code.
I know that this isnt the best source, but as I found discussed in Quora:
Contrary to what their name implies, Python lists are actually arrays(...).
Specifically, they are dynamic arrays with exponential
over-allocation, which allows code like the following to have linear
complexity:
lst = []
for i in xrange(0, 100000):
lst.append(i)
Alternative implementations like Jython and IronPython seem to use
whatever native dynamic array class their underlying language
(respectively Java and C#) provides, so they have the same performance
characteristics (the precise underlying classes seem to be ArrayList
for Jython and C# List for IronPython).
(...)arrays technically store pointers rather than the objects
themselves, which allows the array to contain only elements of a
specific size. Having pointers all over the place in the underlying
implementation is a common feature of dynamically typed languages, and
in fact of any language that tries to pretend it doesn't have
pointers.
Dictionaries
As the official docs puts in their "History and Design FAQ"
CPython’s dictionaries are implemented as resizable hash tables.
Compared to B-trees, this gives better performance for lookup (the
most common operation by far) under most circumstances, and the
implementation is simpler.
Dictionaries work by computing a hash code for each key stored in the
dictionary using the hash() built-in function. The hash code varies
widely depending on the key; for example, “Python” hashes to
-539294296 while “python”, a string that differs by a single bit, hashes to 1142331976. The hash code is then used to calculate a
location in an internal array where the value will be stored. Assuming
that you’re storing keys that all have different hash values, this
means that dictionaries take constant time – O(1), in computer science
notation – to retrieve a key. It also means that no sorted order of
the keys is maintained, and traversing the array as the .keys() and
.items() do will output the dictionary’s content in some arbitrary
jumbled order.
In Conclution
There are two separate things about a language: one involves how it should work, with it syntax, semantics, logic and philosophy. On the other hand you have the actual implementation of that language in a specific runtime, interpreter or compilation.
This way, although (in theory) you have one Python or one Javascript, you could have CPython, IronPython Jython, etc; and in the other hand, you have SpiderMonkey, V8, etc.
But referring to how each runtime implements the language features of Arrays/Lists and Objects/Dictionaries and how analogous they are, it seems that Javascript has chosen a inheritance model based on prototypes that makes everithing a kind of object; so both Objects and Dictionaries are more like a hash table than an actual array.
On the other hand, Python has a more flavores in respect of data structures, both in their libraries and in how the interpreters deal with them, making use of arrays or dynamic arrays to bring to life the Pyton's Lists, and using hash tables for the dictionaries, making them more similar to the objects in javascript.

Categories

Resources