Im not really getting into the details of WHY doing this as its needed.
Supose i have a simple object.
var obj = {};
Lets say i want to access a random property of that object
obj.randomProp
This is getting me undefined.
Now, would it be possible, for that obj.randomProp return me another empty object ( {} ) ?
Of course, with no property declaration as obj.randomProp=123. I was thinking on this to be dynamic, somehow like a default property getter as if everytime you try to get a property of this element, you will get a new empty object for it.
Is this possible in JS ?
Related
I have a javascript app that reads a json file on the server; the function that reads the json file returns an object.
Until now I was using that object (it represents an album of photos) in the app, but now I want to make it an instance of a class, so that I'm going to manipulate it through the class methods.
Surely I'm doing something like:
var album = new Album(object);
My question is: what is the best way to generate the class properties in the constructor? can I iterate on the object properties with something like:
Object.keys(object).forEach(function(key) {
this[key] = object.key;
}
or should I assign manually each object property to the corresponding class property?
In this case, I'm going to say best is a matter of opinion. What you are doing will work and is clean and simple but it should fail due to this and the function reference also due to the missing ).
The following version should work for you.
Object.keys(object).forEach((key) => {
this[key] = object[key];
})
I have an odd situation in my Javascript code which I cannot explain. So far it has been observed only on Safari/Mac.
I have a line like this:
dict[id].sliceHovered = true;
And sometimes it throws an error:
Attempted to assign to readonly property.
Also:
dict is a bare blank object which I create myself with dict={}.
id is supplied by outside data, so it can be anything (I don't yet know which particular value causes this).
sliceHovered is obviously not a name of something that Javascript has built
in.
The objects in the dict are of my own type. They have a sliceHovered member, but it's not a Javascript defined property (as in Object.defineProperty()), just a regular property (the constructor executes this.sliceHovered=false).
"use strict" is on.
Object.freeze(), Object.seal(), Object.preventExtensions() and const are not used anywhere in the entire codebase.
Thus it's extremely puzzling as to how such an error could be thrown here. If I had an indexing error and dict[id] would be undefined or null, the error would be different. My only idea is that since the dict is created as dict={} then it inherits from Object and maybe id maps to some inherited property. But that means that the object returned from dict[id] would have to be read-only itself, because sliceHovered is definitely not a name of an existing Javascript property.
However I cannot think of any Javascript objects that would be intrinsically read-only like that.
Any ideas what could be wrong here?
You can check this situation
My only idea is that since the dict is created as dict={} then it inherits from Object
with: var dict = Object.create(null);
Also try to use Object.getOwnPropertyDescriptor(dict, id) to make sure descriptors have right values.
I've been working angular for probably six or so months and so have been working a lot more with JSON and objects in javascript. This situation I've been running into has been frustrating and I don't understand the reasoning. Maybe it's my inexperience with JS and so I don't know the reasoning or maybe I'm just doing it wrong but I'd appreciate any insight into this.
Example an object:
var data =
{
"object":
{
"Key":"Value",
"stuff":"here"
},
"array":
[
{
"Name":"Pizza Face",
"id":7
},
{
"Name":"Maple bar",
"id":1
}
]
}
So, let's say I want to add an object to the array. Easy, right?
var newObject = {"Name": "Master Sword", "id":2}
data.array.push(newObject);
But, let's say I want to add the object to the array before the array exists. The above method errors out saying Cannot read property 'push' of undefined. Instead, I have to wrap a condition around it.
var newObject = {"Name": "Master Sword", "id":2}
if(data.array){
data.array.push(newObject);
}
else{
data.array = [];
data.array.push(newObject);
}
I am allowed to add new objects to data whenever I want. However, woe unto me should I try to add an object within an object.
Example:
data.newObject = {"Name": "Master Sword", "id":2}
newObject will be created in this case and everyone is happy.
data.newObject.Name = "Master Sword"
FAIL! Cannot set property 'Name' of undefined
So...why doesn't JS just create newObject with the laid out key value pair? Or when I try to push to an array that doesn't exist why not just create the array rather than error out?
I want to be clear, although this is frustrating to me my purpose of this question isn't to complain. It's to ask if I'm doing this wrong. Do I really need a condition to check if the object/array exists before trying to add to it? Is there a better way to do this?
You are trying to create objects via chaining. The problem with that is except the last part in the chain, all the previous ones must be already defined Javascript Objects.
a.b.c.d = new Object(); // a,b,c must be already defined, cannot have cascading here
So, when you say data.newObject.Name = "Master Sword";, the newObject should have been defined earlier (you already had a data object I assume). This is how it has to work (probably in every language that follows at least some semantics). To get around such a problem, you can always create a new generic object say:
var myComplexObject = function() { //add all reusable object constructors here };
Populate your complex object any way you like, e.g. creating a new empty object in this constructor and add Prototypes to this constructor to expand the functionality. Write once and iterate forever over that. You could build a library suited to your requirements. That is how it should be done.
P.S.: Probably, for the checking part you could encapsulate in a try{}catch(e){} block.
The method push is located on a javascript Array object, unsurprisingly that method will not work on either null or undefined. This is the same for pretty much every programming language.
When calling data.newObject = {"Name": "Master Sword", "id":2} you are quite literally setting the property to a new object, this is a very different scenario to the above.
That´s because when you try to reference a key of an object, if that key doesn´t exist then that key will be kind of created and the undefined value will be assigned to it. undefined is just a JS Value type. If you want to check that "undefined" is not an error, just note that "undefined" is written with gray color on the console. (Errors have the red color).
If you assign an object to a key of other object, and you want to add properties to it, that won´t represent a problem at all.
But if you try to add a property to a key that can be initialized with undefined value, then it's reasonable that you will get an error message. Remember, JS allows you to store any value type you want on objects.
I suggest you to read a little bit more about objects, and the undefined value in JavaScript.
Hope that it helps.
It's super late and my mind is blanking right now, but let's say I have variable filename and it's storing the name of another variable marker. The variable marker is an array and contains the object & property position: new google.maps.LatLng(42.2550,-114.3221).
I've been stupidly trying to access it via filename.position which of course returns undefined, since it's searching the literal filename for a 'position' property that does not exist.
But how could I pull marker.position by using filename? Is there some nifty jQuery trick for, uh, 'resolving' a variable to its contents? I'm brain fried. I know I've done this before.
If it's possible in your script, you can store the data not just in variable, but in a property of some object (usually it's more convenient to use global one).
For example
var myObj = {};
myObj.marker = new google.maps.LatLng(42.2550,-114.3221); // or anything else
Then you will be able to get this property using a variable like this:
myObj[filename].position
In this case i would also recomment to check for myObj[filename] existance using typeof structure, just to make sure such property exists in myObj.
if (typeof myObj[filename] !== "undefined") {
// do something
}
As apsillers noted, you could use global window object for this as well. But if your marker variable was defined inside some other function (i.e. not global), you won't be able to access it with window.marker or window[filename] as it will be out of scope.
Second way is to use eval() function which i'd strongly recommend to avoid.
Try this :
window[filename].position;
I have a js object and i'm trying to access it directly without having to do something like :
for(i in data) { obj = data[i] }
is there a better way to access this object without looping ? (i'll always have 1 result)
here is the firebug result for console.log(data) :
No, you can't access a property without knowing its name (aside from using fancy for-of-loops). And to get that name, you only can enumerate the properties with a for-in-loop or use Object.keys/….getOwnPropertyNames.
If you know that you always have exactly one key in your object, you might have chosen the wrong data structure.