JS. Object in array? - javascript

I'm learning js, find this code:
var arr = [
{id: 111, now: '12.02.2014'}
];
What is this? I know that var arr = [ ... ] - array, but what is {} in array and how i can work with this data and display this ?

{} is the syntax for creating an object. It's called an object initializer, but it's frequently called an "object literal".
So what you're doing there is creating an object which has id and now properties, and putting that object into an array as its only entry.
...how i can work with this data and display this ?
To display the id, for instance:
console.log(arr[0].id);
What that does:
arr[0] - retrieve the first entry in the array. In our case, it's an object.
.id - Get the value of the id property from that object.
We could also write it like this:
var obj = arr[0];
console.log(obj.id);
Alternately, if we didn't know in advance what property we wanted but we were given a string containing the name of the property, we could use [] with the object as well:
var nameOfProperty = "id";
var obj = arr[0];
console.log(obj[nameOfProperty]);
JavaScript has both the dotted syntax (obj.id), and the bracketed syntax (obj["id"]) for accessing object properties, where with the latter you can use any string (including one from a variable).

Yes, that is an object inside an array. In truth, all values, from numbers to functions to arrays, are actually objects.
You can access this object in the same way as you would any item of an array. (arr[0])
You can then access properties of the object, for example arr[0].id.
For more about objects, take a look at Objects on MDN.

Related

Why does a JavaScript array item created via dot notation exist but not get counted in array.length?

Although counterintuitive, it is possible to create a JavaScript array "property" using dot notation:
const arr = [];
arr.dot = "notation";
console.log(arr.dot); // "notation"
Weird, but ok. However, the array's length still registers as 0:
const arr = [];
arr.dot = "notation";
console.log(arr.dot); // "notation"
console.log(arr.length); // 0
Two questions:
Why is the array's length not impacted by the property assigned via dot notation?
Why is it possible to assign a property to an array via dot notation?
A JavaScript array is just an object. You're setting the property dot on the object.
You can confirm that an array is an object by doing:
typeof arr.
The length property is computed based on the number of numeric entries in the array.
Here's an excerpt taken from developer.mozilla.org:
Arrays cannot use strings as element indexes (as in an associative array) but must use integers. Setting or accessing via non-integers using bracket notation (or dot notation) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array's object property collection. The array's object properties and list of array elements are separate, and the array's traversal and mutation operations cannot be applied to these named properties.
That dot notation is actually assigning a property to the array, not pushing a new value!
const myArray = ['apples', 'bananas'];
console.log(myArray);
myArray[2] = 'peach';
console.log(myArray);
I assume this is what made you look towards objects, which do this for assignment:
const myObject = {
id: 1,
name: 'Pig',
type: 'animal',
}
// Standard dot-notation assignment
myObject.sound = 'Oink!';
console.log(myObject);
// "Computed" assignment
myObject['emoji'] = '🐷';
console.log(myObject);
Here's a good read on the topic above https://ui.dev/computed-property-names/.
Back to the question at hand, though: why can't I do this:
const myArray = ['choclate', 'strawberry'];
myArray.pinapple = 'Tasty';
Arrays are essentially lists. It doesn't make sense to add an attribute (i.e. "describer") to a list.
Don't get me wrong - it is perfectly alright to set properties of an Array (as it is based off JavaScript objects), but it isn't used in the way that you're thinking of.
Here's an example of when I might use the "dot notation" assignment for an Array:
let zoo = ['Dolphin', 'Lion', 'Monkey'];
console.log(zoo);
// In-built property
console.log('I have', zoo.length, 'animals in my zoo!');
// Now, let's add a property "income"
zoo.income = 500;
console.log('My zoo has £%s', zoo.income);
// We can use this like a normal object property
zoo.income += 50;
console.log('My zoo has £%s', zoo.income);
// Let's create a method for when the zoo goes out of business
zoo.closeDown = () => {
zoo = [];
zoo.income = 0;
return true;
}
zoo.closeDown();
console.log(zoo);
console.log('My zoo has £%s', zoo.income);
Why would I want to do this? In this example, I could've used an object. But it's possible that it makes more sense to keep the animals in my zoo as an array, and then build up the methods and properties from there.
Okay, but how do I get a list of these properties/methods then?
const myArray = ['Foo', 'Bar'];
myArray.isCool = true;
console.log(myArray);
console.log(myArray.length);
let i;
for (i in myArray) {
console.log(i, myArray[i]);
}
The for (i in ...) syntax can be used here, as we are iterating through the properties of the array as an object. As we know from before, Arrays extend the Object class (kind of).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
length only counts the numeric properties.
Arrays are objects, so you can add other properties to them.
You don't even have to use dot notation, you can write arr["dot"] = "notation";

Index of javascript object in array of objects

I have an array of objects in javascript, something like
var arrayobj = [{a:'a'},{b:'b'},{c:'c'}] (but with more complex values).
Now I check the index of some object manually, like arrayobj[1]
And I got Object {b: "b"}
Now I type arrayobj.indexOf({b:'b'});
and the response is -1 (aka not found).
Anyone could tell me why this happens? I have read the documentation on indexOf method and arrays, but I still have no clue.
Thanks in advance!
indexOf checks for equality (specifically strict equality, ===, but it doesn't matter for this question). Two different objects are not equal to each other even if they have the same properties. The object in your array and the one you pass to indexOf are different objects, and so they don't match.
If you searched for the same object, it would find it:
var b = {b:'b'};
var arrayobj = [{a:'a'},b,{c:'c'}];
console.log(arrayobj.indexOf(b)); // 1
The indexOf method returns the first index at which a given element can be found in the array, or -1 if it is not present.
arrayobj is an array of objects, In first case arrayobj[1] it will return the element at index 1.
In second case arrayobj.indexOf({b:'b'}) is not referring to the object which in the arrayobj but it is a different object.
arrayobj.indexOf({b:'b'})
You are supplying a new object in the indexOf method although contents are same. IndexOf will check for strict equality so references of the objects need to be the same
When you call arrayobj.indexOf({b:'b'}) the Object {b:'b'} is different from the object in your array. These 2 objects have the same "value" but are distinct in the memory.
For exemple if you do this :
var object = {b:'b'}
var arrayobj = [{a:'a'},object,{c:'c'}]
or
var arrayobj = [{a:'a'},{b:'b'},{c:'c'}]
var object = arrayobj[1]
arrayobj.indexOf(object) will return 1 because it's really the same object and not a "copy"
Javascript IndexOf function will work only for value types and not for reference types in your case. Like when you are passing {b:'b'} to indexOf function then it is all in all a complete different object / reference. If you first fetch object from list and then check that reference in list then it will definitely return greater then -1 if object / reference exist
var arrayobj = [{a:'a'},{b:'b'},{c:'c'}];
var obj = arrayobj[1];
console.log(arrayobj.indexOf(obj)); console.log(arrayobj.indexOf({b:'b'}));
you can use for loop instead of built-in function.

Javascript array index

Sorry for asking a noob question but if I have an array:
MyArray["2cd"]="blah1";
MyArray["3cx"]="blah3";
MyArray["8cz"]="blah2";
And a string myStr="2cd";
And then I use MyArray[myStr] to get the value of blah, how can I get the number I am accessing in the object/array or 0 in this case?
If I may read between the lines, it sounds like you're thinking that the code you posted:
MyArray["2cd"] = "blah1";
MyArray["3cx"] = "blah3";
MyArray["8cz"] = "blah2";
will automatically become the equivalent of:
MyArray[0] = MyArray["2cd"] = "blah1";
MyArray[1] = MyArray["3cx"] = "blah3";
MyArray[2] = MyArray["8cz"] = "blah2";
and therefore you can get the string "blah1" either of these two ways:
var foo = MyArray[0]; // sets foo to "blah1"
var bar = MyArray["2cd"] // also sets bar to "blah1"
But that's not how JavaScript works.
You certainly can set things up so you can use my MyArray[0] and MyArray["2cd"] to fetch the same value, but you have to do it explicitly as in my example.
One thing you didn't mention is how you declared MyArray itself. Is it an Array or an Object? That is, before the code you posted, did you create MyArray with:
var MyArray = {}; // or equivalently, var Array = new Object;
or:
var MyArray = []; // or equivalently, var Array = new Array;
The first example creates an Object, the second an Array.
What is a bit confusing is that JavaScript has both of these two types, which in many cases you can use somewhat interchangeably. But it's customary to use an Object when you are using arbitrary (generally but not necessarily non-numeric) keys into the object, as in your example. Conversely, it's customary to use an Array when you are primarily using strictly numeric indexes.
In fact, JavaScript's Array type inherits from the Object type. An Array is simply an Object with some additional behavior:
An Array has additional methods such as .push() which appends an item to the array.
An Array has a .length property which is automatically updated when you add elements with .push() or a direct array[123] assignment, or when you remove elements with .pop() or other methods.
What JavaScript doesn't have, as Fabrício pointed out, is an "associative array" that behaves like what you might find in some other languages. It has Objects and it has Arrays (which inherit from Objects), and you have to deal with each of those on their own terms.

Can an Object object be coerced into an Array object?

Crockford writes in http://javascript.crockford.com/survey.html:
"There are two ways to make a new array:
var myArray = [];
var myArray = new Array();"
So I'm confused by these two lines in some AJAX code I am reading:
var obj={}; // obj is an Object object (i.e. a hash table)
obj[4] = 'x'; // now obj is suddenly an Array object via an integer key?
In JavaScript are an object and an array really just the same thing, but with a variant on the key type?
In other words, is this the same as in php where we can use either a name (string) or an integer for a hash key?
I've Googled for an answer on this but can't seem to nail down an article which discusses this issue.
One possibility that comes to mind is that perhaps the first line is syntactic lint because the 2nd line overwrites the previous definition of obj as it creates a new Array object.
it does not become an array, it is simply an Object with a '4' property, like this:
var obj = {
'4': 'x'
};
it is just converted to a string when used as a property like obj['4'] = 'x';
Everything but primitive datatypes is an object in JavaScript. Objects can have a properties and there are two ways to access object properties:
Dot notation, foo.bar, which you can use as long as the property name is a valid identifier.
Bracket notation, foo['bar'] which you have to use if the key is not a valid identifier [spec]. For example, if it is a number, or contains a space or you have a variable with the name.
Hence, bracket notation is not a characteristic of arrays and if you see it, it does not mean the value is an array. It is simple one of two ways of accessing properties.
The elements of an array are just properties with numeric keys. Arrays are built on top of objects and implement some additional methods which treat these numeric properties in a special way. For example the .length property is automatically updated when you add new elements. But ultimately they are just normal properties.
In your example you have a simple object. You have to access the property with obj[4] or obj['4'] because obj.4 is invalid since 4 is not a valid identifier (basically everything that you can use as variable name is a valid identifier. var 4 = 'foo'; is invalid).
And since arrays are just objects, if you could use numbers as identifiers, you were also able to access an element with arr.4.
As far as I know, no, an object can't be coerced into an array. But, it can look and act like an array, and that's what's happening here. Numbers, and anything else that can be coerced to a string, are perfectly valid property names for Javascript objects, so
obj[4] = 1;
obj['spam'] = 2;
are both valid ways of setting a property on the object. That doesn't make the object an array. An Array is a special class of object with specific methods (.slice(), .concat(), etc) and a length property that's kept up to date with the number of items in the array.
Yes
Javascript Array is very different from tradition array, you can think of it as object.
var array = [1,2,3] is equivalent to var object = {'0' : 1, '1' : 2, '2' : 3}
except array inherited from Array.prototype and object inherited from Object.prototype, where Array.prototype will contain method such as length.
Javascript is a loosely-typed, prototype-based language. Even primitive types like a boolean can be treated like an object (though you aren't going to get far). Almost everything in javascript is, at root, an object.
Understanding this, an array IS an object. You can arbitrarily add properties to any object:
var xml = new XMLHttpRequest();
xml[4] = 'x';
console.log(xml);
That object is still an instance of XMLHttpRequest. It now has a property labeled 4 with a value of x. You can treat anything like this -- even a function:
var test_func = function () {
alert('woah!');
}
test_func[4] = 'x';
console.log(test_func[4]);
The take-away here is that the obj[key] = value notation is NOT indicative of an "array" type, like it is in languages such as PHP. Rather, it is an alternate way to access properties of any object, and is equivalent to obj.key = value (you can't use obj.4 = 'x', though, that's invalid syntax). The other take-away is that any object in javascript can be modified or used in pretty much any way. You shouldn't misuse objects, but you can
Check it out here: http://jsfiddle.net/w2AqJ/
Documentation
Array on MDN - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array
Javascript "associative arrays" considered harmful by Andrew Dupont - http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/

How do I access the first key of an ‘associative’ array in JavaScript?

I have a js 'associative' array, with
array['serial_number'] = 'value'
serial_number and value are strings.
e.g. array['20910930923'] = '20101102'
I sorted it by value, works fine.
Let's say I get back the object 'sorted';
Now I want to access the first KEY of the 'sorted' array.
How do I do it? I can't think I need an iteration with
for (var i in sorted)
and just stop after ther first one...
thanks
edit: just to clarify, I know that js does not support associative arrays (that's why I put it in high commas in the Title).
2021 Update
Since ES6, properties with string keys are enumerated in insertion order. Here's a nice summary. My original answer from 2010 was correct at the time and is preserved below:
Original answer
JavaScript object properties are specified to have no order, much though many people wish it were different. If you need ordering, abandon any attempt to use an object and use an Array instead, either to store name-value objects:
var nameValues = [
{name: '20910930923', value: '20101102'},
{name: 'foo', value: 'bar'}
];
... or as an ordered list of property names to use with your existing object:
var obj = {
'20910930923': '20101102',
'foo': 'bar'
};
var orderedPropertyNames = ['20910930923', 'foo'];
Try this:
// Some assoc list
var offers = {'x':{..some object...}, 'jjj':{...some other object ...}};
// First element (see attribution below)
return offers[Object.keys(offers)[0]];
// Last element (thanks to discussion on finding last element in associative array :)
return offers[Object.keys(offers)[Object.keys(offers).length - 1]];
Actually JavaScript doesn't support associative arrays, so you can't loop through it in an implied order (e.g. you can't access it via the indexer property array[0] won't access the first element in your object). The syntax is what makes it look like it does, but in reality it doesn't. So you have no "Order" to your objects.
http://www.hunlock.com/blogs/Mastering_Javascript_Arrays
Javascript does not have, and does not
support Associative Arrays. However…
All arrays in Javascript are objects
and Javascript's object syntax gives a
basic emulation of an associative
Array. For this reason the example
code above will actually work. Be
warned that this is not a real array
and it has real pitfals if you try to
use it. The 'person' element in the
example becomes part of the Array
object's properties and methods, just
like .length, .sort(), .splice(), and
all the other built-in properties and
methods.
Just thinking off the top of my head, but could you have another array with the key value pairs swapped?
So the answer would be arrayKeyValueReversed['20101102'] = '20910930923';
When you sort the array, use the first item (array[0]) as the key to get the value in the arrayKeyValueReversed.

Categories