Difference between associative [],{} and object in javascript [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between an array and an object?
The item exists in the array but it says that the array is 0 length?
I m a bit confused in object and associative array in javascript. I read this :question but this question says that there is not much of a difference in both. I wrote this in the console:
var a = [];
a["A"] = 1;
var b = {};
b["B"] = 2;
var c = new Object();
c["C"] = 3;
output for above are as:
a gives {A : 1}
b gives {B : 2}
c gives {C : 3}
All above three cases gives same reault as in they all gives an object. Question is how all above 3 cases are treated in javascript.

An array is also an object, that's why you can use non-numeric indices also. Those will be added as properties to the array object, not part of the array data.
The difference between an array and an object, is that the array counts properties with a numeric index as being part of the array data, and updates the length property accordingly. (Also the Array object has some specific methods to work with the array data.)
var a = [];
a[42] = 1337;
Now the length has changed to include the item:
alert(a.length); // shows 43
Using strings or numbers as index doesn't matter, a numeric index counts even if it's a string:
alert(a[42]); // shows 1337
alert(a["42"]); // shows 1337
Reducing the length removes the properties outside it:
a.length = 10;
alert(a[42]); // shows undefined

In your example, b and c are essentially the same thing, because {} is the equivalent of new Object().
Coming back to a, it's defined as an Array which is a special kind of Object in the sense that numeric properties (based on uint32) are treated differently. Its length property gets updated when those properties are added and removed.
When you use 'A' as an index, it gets treated as a regular property, defined by how Object works with properties, so you can access it as a.A or a['A'] whereas an index of [5] can only be accessed using a[5].
Normally, the debug output of an array is always [] unless the length property is non-zero, so the output you've shown is somewhat irregular.
Trivia
According to the ECMAScript documentation, a particular value p can only be an array index if and only if:
(p >>> 0 === p) && (p >>> 0 !== Math.pow(2, 32) - 1)
See also:
The item exists in the array but it says that the array is 0 length?

Let's start by clarifying something:
new Object() is the same as {}
new Array() is the same as []
The latter are just shortened forms of the former.
Behind the scenes, everything in javascript is basically an object (this is an exaggeration but fairly accurate). Arrays are simply derived from objects. Here's a fairly rudimentary example of what an Array REALLY looks like:
var myArray = {};
myArray[0] = 'value1';
myArray[1] = 'value2';
myArray[2] = 'value3';
myArray[length] = 3;
The prototype of an array contains all the methods. For example:
// myArray#push
myArray.prototype.push = function(val){
myArray[this.length] = val;
this.length++;
}
Another way to illustrate this is to take an array and add keys that are not numeric:
var example = [];
example.push(0);
example.push(1);
example.push(2);
example['a'] = 'a';
example['b'] = 'b';
example['c'] = 'c';
example.log = function(){
for(var i = 0, l = this.length; i < l; i++){
console.log( example[i] );
}
console.log(this['a']);
console.log(this['b']);
console.log(this['c']);
}
// example[0] is 0
// example[1] is 1
// example[2] is 2
// example.log is my custom function
example.log(); // results in
// 0
// 1
// 2
// a
// b
// c
Also, don't always believe everything the console tells you. For example, if you do this:
var console_confusion = {};
console_confusion.length = 100;
console_confusion.splice = function(){ /* do absolutely nothing */ };
console.log( console_confusion );//results in
//
// in Chrome:
// [undefined × 100]
//
Chrome will interprut anything with a numeric length property and a splice function as an Array. This is why jQuery objects look like Arrays in the console.

Please read the following article – http://www.2ality.com/2012/12/arrays.html
In short, “regular arrays”, denoted as [] in JavaScript, are also objects, just like {}, but they have length property and “numeric” keys (“indicies”), plus their internal __proto__ property points at Array.prototype object, which holds all Array methods, such as push or forEach etc.

first is an array
second is an object array
third is an array object

Related

Can't create JS object with array indices as key & value?

Task: convert an array into an object with one key-value pair, where the first array item is the key, and the last array item is the value.
E.g., [1,2,3] should convert to {1: 3}
I can't get it to work as:
function transformFirstAndLast(array) {
var firstLast = {
array[0]: array[-1]
};
return firstLast
}
But only as:
function transformFirstAndLast(array) {
var firstLast = {};
firstLast[array[0]] = array[array.length - 1];
return firstLast
}
...why doesn't the first work? Why can't you index the array for the key & value?
You could pop the last element and take a computed property for the object. (For the first element, you could take Array#shift, if you like to do it in the same manner.)
function transformFirstAndLast(array) {
return { [array[0]]: array.pop() };
}
console.log(transformFirstAndLast([1, 2, 3]));
ES5 with a temporary variable.
function transformFirstAndLast(array) {
var temp = {};
temp[array[0]] = array.pop();
return temp;
}
console.log(transformFirstAndLast([1, 2, 3]));
Take the first is easy, take the last is the size minus one like this:
function firstAndLast(array) {
var ary = {};
ary[array[0]] = array[array.length - 1];
return ary;
}
console.log(firstAndLast([1,2,3]))
First, you must remember than an array is a type of JavaScript object and, in JavaScript, an object property (a.k.a. "key") can be accessed or assigned in two ways:
via "dot notation"
object.property = value;
via array syntax
object["property"] = value;
Next, remember that, in JavaScript, if you assign a value to a property that doesn't exist (using either syntax from above), the property will be created, like in the following:
console.log(window.someNewProperty); // undefined
window.someNewProperty = 17; // This causes the property to be created
window["someOtherNewProperty"] = "Voilla!"; // So does this, just with array syntax
console.log(window.someNewProperty); // 17
console.log(window["someOtherNewProperty"]); // "Voilla!"
Now, moving on to the specifics of an array, it's critical to understand the difference between an object property/key name (which is always represented as a string) and an array index (which is always a non-negative integer up to the max integer in JavaScript). So, if you have an array and seemingly assign a value to a negative index, you are actually creating a property that is named the negative index and not actually adding to the length of the array or making a new indexed position in the array. We can see that here:
var myArray = ["a", "b", "c"];
myArray[-1] = 15;
console.log(myArray.length); // 3 not 4
console.log(myArray[-1]); // 15
// Now to prove that -1 is a string name for a new property and not an index:
console.log(myArray); // Notice no 15 in the indexed values?
// And, if we enumerate the object (not just the indexes), we'll see that we actually created
// a property with [-1], not a new index.
for(var prop in myArray){
// Note that prop is not the value of the property, it's the property name itself
console.log(typeof prop, prop, myArray[prop]);
}
So, to sum up, Arrays have non-negative integer indexes to store the items that make up the length of the array, but Arrays are also objects and have properties, like all other objects do. Any bracket assignments that use anything other than non-negative integers as the key name will become new properties, not array indices.

How to make associative array with number as string in Javascript

I have a code :
var index = 100;
var arr =[];
arr[index.toString()] = "Hello"
The result : index still known as integer not a string. Anyone can explain what's wrong with my code?
You have to declare associative arrays using {}, which creates a new object, because in JavaScript, arrays always use numbered indexes.
You need to declare an object: var arr={};
arrays use numbered indexes.
objects use named indexes.
var index = 100;
var arr ={};
arr[index.toString()] = "Hello";
console.log(arr);
How to make associative array with number as string in Javascript
JavaScript doesn't have associative arrays in the sense that term is frequently used. It has objects, and as of ES2015 (aka "ES6"), it has Maps.
The result : index still known as integer not a string. Anyone can explain what's wrong with my code?
The index variable's value is still a number, yes, because you haven't done anything to change it. But the index in the array is a string (and would be even if you didn't use .toString()), because standard arrays aren't really arrays at all1, they're objects with special handling of a class of properties (ones whose names are strings that fit the spec's definition of an array index), a special length property, and that use Array.prototype as their prototype.
Here's proof that array indexes are strings:
var a = [];
a[0] = "zero";
for (var name in a) {
console.log("name == " + name + ", typeof name == " + typeof name);
}
That said, you don't want to use an array when you want a generic object or map.
Here's using a generic object for name/value mappings:
var o = Object.create(null);
var name = "answer";
o[name] = 42;
console.log(o[name]); // 42
The property names in objects are strings or (as of ES2015) Symbols. I used Object.create(null) to create the object so it wouldn't have Object.prototype as its prototype, since that gives us properties (toString, valueOf, etc.) that we don't want if we're using the object as a map.
Here's using a Map:
var m = new Map();
var name = "answer";
m.set(name, 42);
console.log(m.get(name)); // 42
The main advantages Maps have over objects are:
Their keys can be anything, not just strings or Symbols
They're iterable, so you can use for-of to loop through the mappings they contain
Maps have a size property telling you how many entries they have
Maps guarantee that iteration of their entries is performed in the order the entries were added to the map
With ES6, you could use a Map, which holds any type as key.
var map = new Map;
map.set(100, "Hello");
map.set('100', "Foo");
console.log(map.get(100)); // 'Hello'
console.log(map.get('100')); // 'Foo'
console.log([...map]);
JavaScript does not support arrays with named indexes, in JavaScript, arrays always use numbered indexes.
If you use a named index, JavaScript will redefine the array to a standard object.
After that, all array methods and properties will produce incorrect results.
As you can see in the following example:
var person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46;
var x = person.length; // person.length will return 0
console.log(x);
var y = person[0]; // person[0] will return undefined
console.log(y);

javascript dynamic array declare and initialize with IE

I have this example work fine with chrome and firefox
var array = [];
array.a = 1;
array.b = 2;
console.log(array)
in chrome and firefox return a
objectArray [ a:1 b:2 ]
but IE return objectArray[] lenght 0
any idea?
{} creates an empty literal object (= key-value object). equal to new Object()
[] creates an empty array. equal to new Array()
Example:
var obj = {};
obj.a = 1; //add a key-value
console.log(obj);
var array = [];
array.push(2); // add a value
console.log(array);
In JavaScript arrays are also Objects and the following statements does not cause error and are still valid:
var array = [];
array.a = 1;
I don't know how your code can works on Chrome. You initialize a variable but you modify another variable.
Anyway, you want to make an Object and not an Array.
Try with this code :
var test = {};
test.a = 1;
test.b = 2;
console.log(test)
But in IE, you'll maybe get [object Object] in your output. It's because IE doesn't know how to print an object correctly.
Arrays are arrays ([]) and associative arrays are plain objects ({}) in JavaScript.
Use the following instead:
var array = {};
array.a = 1;
array.b = 2;
console.log(array);
And beware that objects do not return amount of properties in length. Instead you may use Object.keys(array).length or do count them with for loop.
JavaScript doesn't have associative arrays. In JavaScript everything is an object including arrays, which are instances of an Array object and just like with any other object you can add properties to them:
var test = [];
test.a = 3;
test['b'] = 4;
test[3] = 6;
test['4'] = 6;
So basically, elements of an array are actually properties of an Array object, but not all properties can be considered elements. According to the ECMAScript Language Specification (15.4 Array Objects) a property is an element only if it's name meets the following criteria:
A property name P (in the form of a String value) is an array index if
and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not
equal to 232 - 1.
This is important because the length property, as well as methods such as forEach, take into account only properties which meet this criteria.
ECMAScript 6, however, will support Maps:
var myMap = new Map();
var keyObj = {},
keyFunc = function () {},
keyString = "string";
myMap.set(keyString, "value associated with keyString");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");
myMap.size; // 3
myMap.get(keyString); // "value associated with keyString"
myMap.get(keyObj); // "value associated with keyObj"
myMap.get(keyFunc); // "value associated with keyFunc"

How to remove all undefined keys from a javascript array (hopefully when creating the array?)

I have placed my frustrations into a jsfiddle to observe here: http://jsfiddle.net/8ShFr/1/
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
alert('why does this array have a length of ' + brand_new_array.length + '???');
I am doing some calculations client side that require me to set javascript array keys of 1M+ in number.
Not knowing exactly what that number is demands that I iterate through the first 1M+ empty array values before getting to an array key that holds data.
I simply want to set a single large key value for a javascript array without creating a bunch of empty keys before it?
I am using jQuery.each to iterate over the array, and it keeps going through array[0], array[1], array[2], etc... when I only set array[123125] for example.
Just filter out the undefineds.
brand_new_array = brand_new_array.filter(function(n){return n !== undefined});
The reason for the length being 10 is that an array's length is set to the largest index number in the array. However, this does not mean there are 9 other values in there because in javascript an array is at its base an object.
The length is just a property in the object. Arrays in javascript are at their core objects (Array Object 1). They merely act like arrays through an api.
"Whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index" 1
1. ECMAScript Language Specification 15.4 Array Objects
You probably want to just use an object with strings for keys (the keys can be the toString() of Numbers, which will happen automatically if you try to use numbers).
var sparse_array_obj = {};
sparse_array_obj[10003210234] = 4; // Fair dice roll
sparse_array_obj[5] = 17; // Truly random number
sparse_array_obj[900] = Math.random(); // Pseudorandom number
for(var i in sparse_array_obj)
console.log(sparse_array_obj[i]);
The downside is that Javascript provides no guarantees about the iteration order through an object (since its keys are unordered by definition). There are however ways around this, such as:
// Sort the keys in numeric order
var sorted_keys = Object.keys(sparse_array_obj).sort(function(a, b){ return a - b; });
for(var i = 0; i < sorted_keys.length; i++)
console.log(sparse_array_obj[sorted_keys[i]]);
Object.keys needs to be shimmed in older browsers.
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
var result = brand_new_array.filter(function(e) { return e != undefined;})[0];
alert(brand_new_array.indexOf(result));
Travis J is right. The array in your example only contains one entry, but your use of jQuery.each() is making you think there are 10 entries because it iterates from 0 up to the highest index number of the array (defines the length). This is from the jQuery.each() API documentation.
A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties.
Going back to your example:
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
This will result in only one console.log output:
for(var i in brand_new_array)
console.log(brand_new_array[i]);
This will result in 10 console.log outputs:
$(brand_new_array).each( function(i,e) { console.log(e) })
Similarly, this will result in 10 console.log outputs:
for (var i=0;i<brand_new_array.length;i++)
console.log(brand_new_array[i]);
If you really want to stick with using .each() then you can skip the undefined indices like so:
$(brand_new_array).each( function(i,e) {
if (this.hasOwnProperty(i)){ console.log(e) }
})
Filter the falsy items - including undifined:
var a=[1,2,"b",0,{},"",NaN,3,undefined,null,5];
var b=a.filter(Boolean); // [1,2,"b",{},3,5]
The length is 11 because the index starts at 0.
x[0] = undefined
x[1] = undefined
x[2] = undefined
x[3] = undefined
x[4] = undefined
x[5] = undefined
x[6] = undefined
x[7] = undefined
x[8] = undefined
x[9] = undefined
x[10] = "random array value"

O/P of Javascript code [duplicate]

This question already has answers here:
Javascript Object returns junk values
(2 answers)
Closed 8 years ago.
In the below JavaScript code :-
var a = [];
for (i in a) {
alert(i);
}
I am getting o/p as - $family, $constuctor, each, clone, clean, invoke, associate, link, contains, append, getlast, getRandom, include, combine, erase, empty, flatten, pick, hexToRgb, rgbToHex.
Can anybody explain why is that so?Has it got to do something with properties of Array objects and if so then why aren't all the properties alerted? Also , if we take a empty object literal like var a = {} , we don't get any o/p.
Now , if I change the above code like :-
var a = [9,2];
for (i in a) {
if (a.hasOwnProperty(i)) {
alert(a.hasOwnProperty(i));
alert(i);
}
}
I get the output as 0 and 1.Why is that so ? Are those the properties of this Array object (which are also the indexes) ?
The for-in syntax is for objects. It iterates all fields of the object, including methods. When you want to iterate an array, always use this:
for (var i = 0; i < array.size; i++) {
doSomething(array[i]);
}
Your latter loop with hasOwnProperty doesn't iterate over the standard methods of arrays, because your array a inherited these methods from the base Array class, so they aren't it's own properties. But when you explicitely add a method to an array, it should also list the function because it is now an own property:
var a = [9,2];
a.hello = function() { };
for (i in a) {
if (a.hasOwnProperty(i)) {
alert(a.hasOwnProperty(i));
alert(i);
}
}
This should list 0, 1 and hello.
In case you expected it to output 9 and 2 and you wonder why it outputs 0 and 1: That's because the for-in array iterates over the keys, not over the values. And arrays are basically objects where each array element is a property with the array index as a name. So
var a = [9, 2];
is equivalent to this object (plus the stuff inherited from Array):
var a = {
0: 9,
1: 2
}

Categories