Why Are Array-Like Objects Used in Javascript Over Native Arrays - javascript

It's very common in Javascript to come across Array-Like objects with some similarities to the build in Array type but without all of its methods or features. So much so that there are some tricks to convert Array-Like objects to "real" arrays for further manipulation.
This is even mentioned in Javascript: The Definitive Guide.
The questions is why is this pattern so common? Why not prefer the built-in Array type in all these cases?

Well, speaking about core Javascript objects, the arguments is a good example to talk about.
In this case it has been an array-like object since the beginning, appeared in the ECMAScript 1th Edition Specification already as a simple object.
Why? I think at that time there were only four built-in Array methods, and maybe the designer didn't think it worthed too much, later the change was proposed, but Microsoft (part of the TC39 committee) didn't approved the change, the fear of breaking the web has always been present.
Now going to host objects, the DOM, NodeLists come to my mind, I think they didn't wanted to use the native Array type due the dynamic behavior of these objects.
NodeLists generally are live objects, their structure is reflects any change on the underlying DOM structure...
Personally I like array-objects, because they are really lightweight, before ECMAScript 5, there were a lot of restrictions in core methods, regarding the usage of user-defined array-like objects.
For example, the apply method of function objects, in ECMAScript <= 3, allowed only either a real array or an arguments object as its second argument, now in ES5, the following is possible:
var arrayLike = {0: 'hello ', 1:'world', length:2};
(function (a,b) { alert(a+b); }).apply(null, arrayLike);
See also:
Why isn't a function's arguments object an array in Javascript?

Related

What are the semantic differences between `Set` and a `Map` in JavaScript?

It seems that everything you can do with Set you can do with Map? Is this correct?
What are the semantic differences between a Set and a Map?
Edit: the linked "dupe" does not enumerate the semantic differences between the two.
I have retracted my close vote.
A quick google of 'set vs. hashtable' or 'set vs. hashmap' turns up numerous SO questions, mostly in the Java tag, but I didn't see a single answer that actually tackled the difference in a good conceptual way (although a few linked to relevant resources).
Let's start with what data structures are: namely containers for values. The values can be whatever for the most part. Some data structures are homogeneous, some aren't. Some have restrictions (e.g. Map can have arbitrary keys but POJOs can only have string or symbol keys), some don't, some are ordered, some aren't, etc. All of these tradeoffs generally boil down to performance.
A Set is a data structure that holds unique values. Let's compare to an array:
Array.from(new Set([1,2,2,3])).toString() === [1,2,2,3].toString();
// false
Like arrays or lists, Sets in JavaScript are linear: you can traverse them in order*. But unlike arrays (more like lists) Sets are not indexed. You can't say new Set(1)[0];.
Maps on the other hand *ahem* map keys to values (indexed). If I have a Map new Map([['a',1]]), then .get('a') will return 1. Order is not generally considered important for Maps, that what key indexes are for. Nor is uniqueness: new Map([['a', 1], ['b', 1]]) stores the value 1 twice** and you can access it from either key.
Even if, like me, you are primarily a self-taught programmer, I highly recommend familiarizing yourself with basic data structures as it offers valuable insight into problem identification and general solutions. If you find yourself using Array.prototype.shift a lot for instance, you probably wanted a FIFO queue/linked list instead.
* Sets in general are unordered, the retention of insertion order is a JavaScript thing.
** The underlying implementation may as an optimization store it only once, but that is an implementation detail and opaque to you the user.

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.

MongoDB multiple sort properties: How is precedence determined?

According to Mongo's docs, you can specify multiple sort keys like this:
{ $sort : { age : -1, posts: 1 } }
Which they say will sort first by age (descending) then by posts (ascending).
But the sort query is a Javascript object. To the best of my knowledge, although implementations typically iterate over properties in the order they were created, that's not actually part of ECMAScript's spec: object properties officially have no order.
Is MongoDB really relying on arbitrary behavior that could vary by implementation, am I wrong about the ECMAScript spec, or am I missing something in the Mongo docs that lets you tune the precedence some other way?
The console is special, its objects are actually ordered unlike normal EMCAscript so that this can happen.
Here is a linked question from a 10gen employee that states: https://stackoverflow.com/a/18514551/383478
Among other things, order of fields is always preserved.
N.B: It is good to note that V8 (runs MongoDB shell and MR since v2.2 about) has ordered objects in practice anyway.
The only true way in non-V8 JS to keep order is to do key lookups like: How to keep an Javascript object/array ordered while also maintaining key lookups?
Yes you are wrong about the ECMAScript spec. Properties retain their order which is why with some drivers for languages ( e.g Perl orders "hashes" by key name by default, use Tie::IxHash to change that) recommend forms that also maintain an order in the structure to be converted.
At any rate, this is not "really" JavaScript anyhow, but it is BSON. It is borrowed behavior anyhow so the statement really remains the same. The order you specify is preserved.

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.

How to stringify a whole Javascript Object including __proto__ properties?

I am sorry if this is a duplicate, so far I couldn't find the same question.
I have an Object with various methods in my __proto__ member.
Let's call the type of this object myObjectType.
Later on I have to do a JSON.stringify(myObjectType). The problem is that then when I build my object from the previous obtained JSON string the type of my Object is plain Object, I lost all the methods I had.
Does any one see why ?
search google for javascript object serialization.
GSerializer library
There's no standardized way of incorporating functions into JSON data. You can do something yourself — that is, write your own JSON serializer that incorporates functions according to some convention — but with straight standard JSON you get numbers, strings, booleans, and null, plus of course objects with named properties and arrays. No functions, just data.
I'd highly recommend Douglas Crockford's libraries:
https://github.com/douglascrockford/JSON-js

Categories

Resources