properties of object variables how to target them - javascript

What I'm given in my homework is and JS object that looks like:
myObj =
{name:eric, location:belgium, age:24},
{name:jools, location:holland, age26},
{name:mike, location:usa, age:30},
the idea is that somehow if i need to target 'location' holland i need to be able to treat all this like an arary so I can work with indexes (at least that's what I think). I Can't find any example anywhere where people work with this been searching for a bit on 'js object'.
The actual challenge is to be able to put the different values of the 'name' property as innerHTML(or some method that does something similar) of new option elements inside a given select element probably through a loop. Since this is homework, I don't need the actual code for that but a clue on where I can learn more about how these JS object property array type of things work would be nice.
thanks a lot!

Your JavaScript snippet is invalid, something makes me think there was a copy-and-paste error. The answer changes significantly depending on what the code actually looks like.
If it looks like this:
myObj = [
{name:eric, location:belgium, age:24},
{name:jools, location:holland, age26},
{name:mike, location:usa, age:30},
// ...
];
...then you're dealing with an array of objects, where each object has the properties name and location. You can loop through them using a standard for loop with an index variable, counting from 0 to myObj.length - 1 (inclusive), and access the properties of each object via myObj[index].name and myObj[index].location.

Related

What is the accepted convention for when to use an object containing objects vs an array of objects in JSON?

I am currently in the process of writing a GUI which fundamentally allows users to edit/populate/delete a number of settings files, where the settings are stored in JSON, using AJAX.
I have limited experience with JavaScript (I have little experience with anything beyond MATLAB to be frank), however I find myself restructuring my settings structure because of the semantics of working with an object containing more objects, rather than an array of objects. In C# I would do this using a KeyValuePair, however the JSON structure prevents me from doing what I'd really like to do here, and I was wondering whether there was an accepted convention for do this in JavaScript which I should adopt now, rather than making these changes and finding that I cause more issues than I solve.
The sample data structure, which has similar requirements to many of my structures, accepts any number of years, and within these any number of events, and within these a set number of values.
Here is the previous structure:
{"2013":
{
"someEventName":
{
"data1":"foo",
"data2":"bar",
...},
...},
...}
Here is my ideal structure, where the year/event name operates as a key of type string for a value of type Array:
["2013":
[
"someEventName":
{
"data1":"foo",
"data2":"bar",
...},
...],
...]
As far as I am aware, this would be invalid JSON notation, so here is my proposed structure:
[{"Key":"2013",
"Value":
[{"Key":"someEventName",
"Value":
{
"data1":"foo",
"data2":"bar",
...}
},
...]
},
...]
My proposed "test" for whether something should be an object containing objects or an array of objects is "does my sub-structure take a fixed, known number of objects?" If yes, design as object containing objects; if no, design as array of objects.
I am required to filter through this structure frequently to find data/values, and I don't envisage ever exploiting the index functionality that using an array brings, however pushing and removing data from an array is much more flexible than to an object and it feels like using an object containing objects deviates from the class model of OOP; on the other hand, the methods for finding my data by "Key" all seem simpler if it is an object containing objects, and I don't envisage myself using Prototype methods on these objects anyway so who cares about breaking OOP.
Response 1
In the previous structure to add a year, for example, the code would be OBJ["2014"]={}; in the new structure it would be OBJ.push({"Key":"2014", "Value":{}}); both of these solutions are similarly lacking in their complexity.
Deleting is similarly trivial in both cases.
However, if I want to manipulate the value of an event, say, using a function, if I pass a pointer to that object to the function and try to superceed the whole object in the reference, it won't work: I am forced to copy the original event (using jQuery or worse) and reinsert it at the parent level. With a "Value" attribute, I can overwrite the whole value element however I like, provided I pass the entire {"Key":"", "Value":""} object to the function. It's an awful lot cleaner in this situation for me to use the array of objects method.
I am also basing this change to arrays on the wealth of other responses on stackoverflow which encourage the use of them instead of objects.
If all you're going to do is iterate over your objects, then an array of objects makes more sense. If these are settings and people are going to need to look up a specific one then the original object notation is better. the original allows people write code like
var foo = settings['2013'][someEventName].data1
whereas getting that data out of the array of objects would requires iterating through them to find the one with the key: 2013 which depending on the length of the list will cause performance issues.
Pushing new data to the object is as simple as
settings['2014'] = {...}
and deleting data from an object is also simple
delete settings['2014']

jQuery Id Selection and Dynamic Arrays

I have some code I'm struggling with. The good news is the code working as intended for a single instance; after some thought I've decided to feature multiple of these image selectors on a page. This works but the ugly approach of duplicating the code doesn't scale well (e.g. what if you want 50 of these on there?) The snag I've hit is how I can refer to a specific array. Is an array even an ideal solution for this?
The Objective
I have a series of images that a user may select from, up to X amount. The selected image ids are stored in an array and the image is added to a "selected images pool". This occurs by using an onClick for the slider, I obtain the Id from the element attributes. This is where I'm getting stuck.
var dataArray = $(this).closest("[id^=carousel]").data('array');
var slideCounter = $(this).closest("[id^=carousel]").data('counter');
slideCounter = dataArray.length;
The slideCounter returns the length of the string, not the array elements. How can I tell this code to refer to a particular array? See the fiddle for a better idea of the markup and code: jsFiddle
I have no doubt that there is a better approach. I'm relatively new to front end work, I'd appreciate any insights, I've burnt some brain cells on this, thanks!
From looking at your HTML, it looks like when you do this:
var dataArray = $(this).closest("[id^=carousel]").data('array');
what you're trying to do is to read the name of an array with .data() and then somehow turn that name (which is a string) into the array that's in your variable. My guess is that there's probably a better way to structure your code rather than putting javascript variable names in your HTML. I'd probably put a key name in the HTML and then store the arrays in an object where you can access them by that key name at any time.
Without trying to refactor your code, here's an idea for what you were trying to accomplish:
If selectedSlidesIdArray1 is a global variable, then you can do this:
var dataArray = window[$(this).closest("[id^=carousel]").data('array')];
Using the [stringVariable] notation on an object, lets you access a property by a literal string or a variable that contains a string. Since all global variables are also properties on the window object, you can do it this way for global variables.
If selectedSlidesIdArray1 is not a global variable, then you should probably put it in an object and then you can do this:
var dataArray = yourObj[$(this).closest("[id^=carousel]").data('array')];
Instead of trying to translate an arbitrary string into a JavaScript variable of the same name, why not just use another array? You can have nested arrays, which is to say an array of arrays.
Thus, instead of selectedSlidesIdArray1, selectedSlidesIdArray2, etc., you would have one selectedSlidesIdArray with sub-arrays, which you could then pull the index for using a data attribute.

Trouble with "dictionary" creation in JavaScript

OK, first-off let me tell you that I'm too far from being considered experienced in JavaScript... (perhaps I'm even trying to implement something not actually supported by the language?).
So... here we are...
I want to create a structure like this (it's just an illustrative example) :
Addresses
--- John
--- Phone
--- Address
--- Peter
--- Phone
--- Address
So, I've seen (or perhaps I'm just guessing) that I can do something like that (I've run all my tests in Chrome's JavaScript console) :
var addresses = [];
addresses["John"] = {};
addresses["John"].Phone = "12312312312";
// And so on...
However :
If I do addresses['123'] = {}; then a proper 124-entry array is constructed.
If I do addresses['somestring'] = {}; then addresses remains an empty array [].
What am I doing wrong? Is there no native support for proper dictionaries (or map - no matter how this thing is called) in JavaScript?
Please note: I want to be able to progressively add entries to addresses, as well as keys to each address entry (and not just create it in one-shot).
You are creating an array, but then you are using it as an object instead (which is possible because an array happens to be an object). To contain properties rather than numbered indices, you should use an object:
var addresses = {};
addresses["Holmes"] = { Phone: "14", Address: "Baker street 221b" };
JavaScript has Objects and Arrays.
Arrays are a type of Object that treats properties with numerical with special significance. It will have a length property based on the highest value property name (that is a number), and it has methods such as push, pop and forEach to manipulate its numerical members based on their number.
If I do addresses['123'] = {}; then a proper 124-entry array is constructed.
You already have an array. That just adds a member called 123 to it and updates its length.
If I do addresses['somestring'] = {};
This will add that member to the array, but it won't appear in any of the regular means of accessing array members. You have to access it by name.
Don't give named properties to arrays. Use a plain object.
Is there no native support for proper dictionaries
An object is as close as you can get.
If you want something ordered use an array with numerical properties.
If you want something with named keys, use an object.
When you do this addresses['somestring'] = {}; you wil get an empty array because {} you are assigning an empty object.
Rather if you do addresses["dd"] = {s: "s"} the addresses will have the object
Javascript does not have dictionaries or maps or associative arrays.
It does, however, have objects which can be quite similar. (They can also be quite different, so that is essential to know.)
To make things more confusing, an array is an object. You can put random properties on an array and it will work -- like an object.
Javascript arrays take integer[*] indexes and adjust the .length property.
Objects take string property names. This is important: If you use something that is not a string, it will be converted into one .. usually called [Object object]
Might want to read this:
http://eloquentjavascript.net/chapter4.html
[*] Yea, yea, yea -- they are really strings behind the scenes. It is easier to think of them as integers and avoid that grief.

How to assign values to objects through a variable that is just a reference to them?

I couldn't really word the question less vaguely, but I think you will understand...
I am developing a game engine in Javascript, and the Scene object, which is a container of many things, has a method that is supposed to change one array in it, specifically the one holding all the things that can be drawn.
This array is accessed like this:
scene.internals.draw
The problem is, it is referenced many times in the method, and I think that the name/path might change. Naturally, I don't want to change every reference to it in the method each time I change the the array's path, so I did this:
var location = scene.internals.draw;
Now, the actual method code and the algorithm can stay intact, and if the name/path of the array in the scene changes, I only need to change that one line.
And it works pretty well for the most part. I can .push(obj) to it, etc, but at one point, I need to "disect" the array, ie, split it in half, add something, and then put it back together, like this:
buff1 = location.slice(0, i); //First slice of the array.
buff2 = location.slice(i, location.length); //Second slice of the array.
//Add something in between those slices.
buff1.push(ob);
location = buff1.concat(buff2); //Problems here!
This worked well while location was just scene.internals.draw, as it changed the array directly. But now, I assign the new value to the local location variable, not the desired scene.internals.draw one!
Question: how can I, using the = operator, assign values to "real" objects, instead of the variables that contain references to these objects (like location)?
The obvious solution would be this, at the end of the method:
scene.internals.draw = location.slice();
This is OK, the only side effect is that I will have to write the original name twice, and edit it twice, which isn't such a big issue. But, I maybe find myself in other situations where I just might need that functionality, so I'd still like an answer.
There is no assignment by reference in javascript, so you cannot do this. What you are doing is usually mistaken for assignment by reference but it is in fact a copy of a reference value which has implications like this.
You probably have a deeper problem somewhere since you are doing this but I don't wanna get into that.
You could do this:
location.splice( 0, location.length ); //Remove all items in the array
location.push.apply( location, buff1.concat(buff2) ); //Push the buffers into the array
To use your term, there are no "real" objects in Javascript - there are only objects, and the variables that hold references to them.
When you assign to location you're just creating an additional reference to an object. The system has no knowledge of which "real" object it was, nor of any other variables that may hold references to it.
So when you reassign to location you're just overwriting that particular reference. Any other original references to the object will stay pointing just where they were.

How do modern browsers implement JS Array, specifically adding elements?

By this I mean when calling .push() on an Array object and JavaScript increases the capacity (in number of elements) of the underlying "array". Also, if there is a good resource for finding this sort of information for JS, that would be helpful to include.
edit
It seems that the JS Array is like an object literal with special properties. However, I'm interested in a lower level of detail--how browsers implement this in their respective JS engines.
There cannot be any single correct answer to this qurstion. An array's mechanism for expanding is an internal implementation detail and can vary from one JS implementation to another. In fact, the Tamarin engine has two different implementations used internally for arrays depending on if it determines if the array is going to be sequential or sparse.
This answer is wrong. Please see #Samuel Neff's answer and the following resources:
http://news.qooxdoo.org/javascript-array-performance-oddities-characteristics
http://jsperf.com/array-popuplation-direction
Arrays in JavaScript don't have a capacity since they aren't real arrays. They're actually just object hashes with a length property and properties of "0", "1", "2", etc. When you do .push() on an array, it effectively does:
ary[ ary.length++ ] = the_new_element; // set via hash
Javascript does include a mechanism to declare the length of your array like:
var foo = new Array(3);
alert(foo.length); // alerts 3
But since arrays are dynamic in javascript there is no reason to do this, you don't have to manually allocate your arrays. The above example does not create a fixed length array, just initializes it with 3 undefined elements.
// Edit: I either misread your question or you changed it, sorry I don't think this is what you were asking.

Categories

Resources