I am a beginner to Javascript and learning the concepts. I came across the below code snippet as part of my learning process.
<script>
var data=[];
data.push("100");
data.push(100);
var object=[];
object.string="100";
object.number=100;
data.push(object);
console.log(data);
</script>
The above code snippet defines an Array and pushes a String, Number and an Object into it. I think this violates the definition of an Array which reads as follows:
Array is a container which can hold a fix number of items and these
items should be of the same type.
I would like to know if Array is the right term to be used in this case as the elements are not of the same type.
You understand/read them incorrect (in case of javascript).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
Arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed.
And yes, this definition is purely for Javascript. For ex: Java arrays are strictly type based.
The "should be" here most likely refers to the fact that logically homogeneous collections are easier to deal with than heterogeneous collections. If you have an array of numbers, you can do aggregate operations such as summing them easily; if you have a mixed array of stuff, you need to pick it apart one by one and can't easily do anything with it. That's often a sign of a badly structured program.
There's no technical reason why collections must be homogeneous, especially in a dynamically typed language like Javascript (more so in statically typed languages).
Related
while I was taking online CS class, the topic was about an overview of how Array and memory works, and the teacher used C as an Example as that you cannot simply add extra element to an existing Array while the Array is already full with element. As a beginner developer who started with JavaScript, even though I know JavaScript is a high level language and Array.push() is already a familiar function to me, but it seems like it doesn't fit such context, out of curiosity, I've search through google and StackOverflow, I just don't see people discussing why JavaScript can just add extra elements to an existing Array.
Does JavaScript simply create a new Array with added element and point the variable I've already assigned to to the new Array or something else?
Arrays in javascript are not the same as an array in C. In C you'll allocate a new array with type and a fixed size and if you want to alter the size you'll have to create a new one. For javascript arrays on the other hand if you have a look at the description of arrays over at MDN you'll see this line.
Arrays are list-like objects whose prototype has methods to perform traversal and mutation operations. Neither the length of a JavaScript array nor the types of its elements are fixed. Since an array's length can change at any time, and data can be stored at non-contiguous locations in the array
So while it is called "array" it is more like a list which lets you resize it freely (and also store anything, because javascript).
There is also another question about the semantics of the push/pop methods here on SO that can shine some more light on those: How does the Javascript Array Push code work internally
A JavaScript Array is not like a C array, it's more like a C++ std::vector. It grows in length by dynamically allocating memory when needed.
As stated in the reference documentation for std::vector:
Vectors usually occupy more space than static arrays, because more memory is allocated to handle future growth. This way a vector does not need to reallocate each time an element is inserted, but only when the additional memory is exhausted. [...] Reallocations are usually costly operations in terms of performance.
How do relatively modern languages such as ruby/python/js etc may store multiple data types in arrays and are still able to access any element from the array using its index in O(1) time?
As far as I understand, we do simple mathematics to determine the memory address pointing to any element, and we do so by the index multiplied by the size of each element of the array.
Firstly, neither the Ruby Language Specification nor the Python Language Specification nor the ECMAScript Language Specification prescribe any particular implementation strategy for arrays (or lists as they are called in Python). Every implementor is free to implement them however they wish.
Secondly, lumping them all together doesn't make much sense. For example, in ECMAScript, arrays are really just objects with numeric properties, and actually, those numeric properties aren't even really numeric, they are strings.
Third, they don't really store multiple data types. E.g. Ruby only has one data type: objects. Since everything is an object, everything has the same type, so there is no problem storing objects in arrays.
Fourth, at least the Ruby Language Specification does not actually guarantee that array access is O(1). It is highly likely that a Ruby Implementation which does not provide O(1) access would be rejected by the community, but it would not violate any spec.
Now, of course, any implementor is allowed to be as clever as they want to be. E.g. V8 detects when all values of an array are numbers and then stores the array differently. But that is a private internal implementation detail of V8.
In memory, a heterogeneous array is an array of pointers. Every array element stores the memory address of the item at that position in the array.
Since memory addresses are all the same size, you can find the address of each address by multiplying the array index by the address size, and adding it to the base address of the array.
TL:DR
Beside the use of the convent Array helper functions (which I could theoretically create for objects), and considering the performance advantage of Object lookups, what reason could be given to use an Array instead of an Object?
Objects
From what I understand, because JavaScript objects use hash tables to lookup their key -> data pairs, the look-up time, no matter the length of the object is very small.
For example if I want a really fast dictionary look up, in the past I've (and we can condense the syntax but that's besides the point) stored dictionary data in JSON as
"apple" : "apple",
and then used
if (Dictionary.apple) console.log("Yep it's a word!");
And the result return very very fast regardless of whether my dictionary contains 30,000 words or 300,000.
Arrays
On the other hand, unless I know the number an array item is attached to, I have to loop through the entire array, causing larger lookup times the further the item is down the list.
The good thing I know of about using an array is that I get access to convenient functions such as slice, but these could probably be created for use with objects.
My Question
So, considering the lookup efficiency of objects, I'd currently choose an object over an array for every situation. But I could easily be wrong about this.
Beside the use of the convent Array helper functions (which I could theoretically create for objects), and considering the performance advantage of Object lookups, what reason could be given to use an Array instead of an Object?
You're comparing apples to oranges here. If you need to map from arbitrary string keys to values, as in your example with "apple", then you use an object. (In ES2015, you might alternatively use a Map instance.)
If you have a whole bunch of oranges, and you want to keep them in a list numbered from 0, you put the oranges in an array and index by which (numbered) orange you want.
The process of locating a property on an object is the same whether the object is a plain Object instance or an Array instance. In modern JavaScript runtime environments, it's safe to assume that the process for looking up number-indexed array properties is appropriately optimized to be even faster than the hash lookup for arbitrary string-named properties. That, however, is a completely separate issue from the nature of the work you need to do and the choice of data structure. Either you have a list of things, such that the order of the things in the list is the salient relationship between them, or you have named things that you need to access by those names. The two situations are conceptually different.
One big difference is the order of elements.
Looping through objects keys can't guarantee any specific order.
Looping through array keys will always give you the same order of elements.
Long story short : I'd like to treat several javascript associative arrays as a database (where the arrays are tables). The relations could be represented by special fields inside the arrays. I'm not interested in the persistence aspect of a database, I only want to be able to query the arrays with a SQL-like language and retrieve sets of data in the form of associative arrays.
My question : Is there any javascript library that has such features ? Otherwise, is there any library that can at least take care of the SQL-like language part ?
Thanks
I believe the closest thing to what you need is the jLinq library. It can operate with js objects and arrays much in the same way you would do with a database, but in a slightly different way. You don't really write queries, but use methods to construct them. Overall it's way better I think.
Some googling found this: http://ajaxian.com/archives/two-js-solutions-to-run-sql-like-statements-on-arrays-and-objects which seemed interesting.
Can I ask why you want to do this?
I came across this question while searching something sort of related. Wanted to share with you (9 years later, I do realize) that I have the same want/need, often, where the script I'm working on has a lot of cross-referencing to do between various sources of information. I use PowerShell. Enumerating arrays of objects, from within a loop, which is enumerating other objects, is just bad/slow/horrible.
To date, my solution has been to take all my arrays and then make hashtables from them, where the key/name is a property value that is common across all the arrays (e.g. ObjectId (GUID)), and the value is the entire object from the array. With this, while in my loop which is enumerating Array#1, I can check for the presence of this current item in any of the other arrays simply by checking the existence of the key in the corresponding hashtables, and that way there's no enumerating the other array, there's just direct , equal effort access to the correct item in the array (but really coming from the newly built hashtable).
So my arrays are just temporary collection buckets, then everything I do from there uses the hashtables, which are just index/lookup tables.
What I was searching for when I stumbled here, was for solutions to keep track of all the different hashtables in the building/planning phase of my scripts.
I'm new to Javascript, and notice that you don't need to specify an array's size and often see people dynamically creating arrays one element at time. This would be a huge performance problem in other languages as you would constantly need to reallocate memory for the array as it increases in size.
Is this not a problem in JavaScript? If so, then is there a list structure available?
Javascript arrays are typically implemented as hashmaps (just like Javascript objects) with one added feature: there is an attribute length, which is one higher than the highest positive integer that has been used as a key. Nothing stops you from also using strings, floating-point numbers, even negative numbers as keys. Nothing except good sense.
It most likely depends on what JavaScript engine you use.
Internet Explorer uses a mix of sparse arrays and dense arrays to make that work. Some of the more gory details are explained here: http://blogs.msdn.com/b/jscript/archive/2008/04/08/performance-optimization-of-arrays-part-ii.aspx.
The thing about dynamic languages is, well, that they're dynamic. Just like ArrayList in Java, or arrays in Perl, PHP, and Python, an Array in JavaScript will allocate a certain amount of memory and when it gets to be too big, the language automatically appends to the object. Is it as efficient as C++ or even Java? No (C++ can run circles around even the best implementations of JS), but people aren't building Quake in JS (just yet).
It is actually better to think of them as HashMaps with some specialized methods too anyway -- after all, this is valid: var a = []; a['cat']='meow';.
No.
What JavaScript arrays are and aren't is determined by the language specification specifically section 15.4. Array is defined in terms of the operations it provides not implementation details of the memory layout of any particular data structure.
Could Array be implemented on top of a linked list? Yes. This might make certain operations faster such as shift and unshift efficient, but Array also is frequently accessed by index which is not efficient with linked lists.
It's also possible to get the best of both worlds without linked lists. Continguous memory data structures, such as circular queues have both efficient insertion/removal from the front and efficient random access.
In practice, most interpreters optimize dense arrays by using a data structure based around a resizable or reallocable array similar to a C++ vector or Java ArrayList.
Javascript arrays are not true arrays like in C/C++ or other languages. Therefore, they aren't as efficient, but they are arguably easier to use and do not throw out of bounds exceptions.
They are actually more like custom objects that use the properties as indexes.
Example:
var a = { "1": 1, "2": 2};
a.length = 2;
for(var i=0;i<a.length;i++)
console.log(a[i]);
a will behave almost like an array, and you can also call functions from the Array.prototype on it.