Discover the object that an attribute belongs to? - javascript

Is there a way in JavaScript to discover the object that an attribute belongs to? I know that sounds ridiculous, here's an example:
Obj = {};
Obj._name = "name";
var x = Obj._name;
In this example, is there a way to discover what object 'x' refers to?
Thank you

Not really, no - there's no back-reference checking or anything like that available in JS.
The only way this would kind of work would be if you had access to all the objects in question, in some kind of a collection, and could check each one for the property value.
This just returns the first object with a value that matches though, it's not guaranteed to be the source of the value.
var myObjs = [
{name: 'one'},
{name: 'two'},
{name: 'three'}
];
function findObjWithVal(val, objs) {
for (var i = 0; i < objs.length; i++) {
for (var p in objs[i]) {
if (objs[i].hasOwnProperty(p) && objs[i][p] === val) {
return objs[i];
}
}
}
}
console.log(findObjWithVal('two', myObjs)); // [object Object] { name: "two" }
What you're asking for is only really possible in a tight-set grouping of objects, with unique property values, where you know x is always a property value of one of the objects from the set, and no other object will have that property value. Pretty specific use case.

If you simply want the object to be attached to the string variable, you could do something like this:
var Obj = {
_name: 'Chad',
_address: '123 Main Street'
};
function string(val, obj) {
var s= new String(val);
s.obj= obj;
return s;
}
var x = string(Obj._name, Obj);
document.body.innerHTML= x + ' ' + x.obj._address; //Chad 123 Main Street
Referring to x would return Chad. But you have access to all the object's properties by referring to x.obj.

Related

Indexing a JSON by index instead of key? [duplicate]

If I have an array like this:
var arr = ['one','two','three'];
I can access different parts by doing this:
console.log(arr[1]);
How can I access object properties by their order rather than by key?
Example:
var obj = {
'something' : 'awesome',
'evenmore' : 'crazy'
},
jbo = {
'evenmore' : 'crazy',
'something' : 'awesome'
};
How would I get the first property for each object–"something" from obj and "evenmore" from jbo–without explicitly using the property name?
Now, a few of you seem to think I'm after something like:
console.log(obj['something']);
This is not the case, I'm specifically looking to target the index, just like the first example - if it's possible.
"I'm specifically looking to target the index, just like the first example - if it's possible."
No, it isn't possible.
The closest you can get is to get an Array of the object's keys, and use that:
var keys = Object.keys( obj );
...but there's no guarantee that the keys will be returned in the order you defined. So it could end up looking like:
keys[ 0 ]; // 'evenmore'
keys[ 1 ]; // 'something'
The only way I can think of doing this is by creating a method that gives you the property using Object.keys();.
var obj = {
dog: "woof",
cat: "meow",
key: function(n) {
return this[Object.keys(this)[n]];
}
};
obj.key(1); // "meow"
Demo: http://jsfiddle.net/UmkVn/
It would be possible to extend this to all objects using Object.prototype; but that isn't usually recommended.
Instead, use a function helper:
var object = {
key: function(n) {
return this[ Object.keys(this)[n] ];
}
};
function key(obj, idx) {
return object.key.call(obj, idx);
}
key({ a: 6 }, 0); // 6
You can use the Object.values() method if you dont want to use the Object.keys().
As opposed to the Object.keys() method that returns an array of a given object's own enumerable properties, so for instance:
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.keys(object1));
Would print out the following array:
[ 'a', 'b', 'c' ]
The Object.values() method returns an array of a given object's own enumerable property values.
So if you have the same object but use values instead,
const object1 = {
a: 'somestring',
b: 42,
c: false
};
console.log(Object.values(object1));
You would get the following array:
[ 'somestring', 42, false ]
So if you wanted to access the object1.b, but using an index instead you could use:
Object.values(object1)[1] === 42
You can read more about this method here.
var obj = {
'key1':'value',
'2':'value',
'key 1':'value'
}
console.log(obj.key1)
console.log(obj['key1'])
console.log(obj['2'])
console.log(obj['key 1'])
// will not work
console.log(obj.2)
Edit:
"I'm specifically looking to target the index, just like the first example - if it's possible."
Actually the 'index' is the key. If you want to store the position of a key you need to create a custom object to handle this.
Yes, it is possible. We can define getters for each index, and return the property value, in the constructor method of the class. See this code.
class className {
constructor() {
this.name = "Bikram";
this.age = 8;
this.x = 89;
this.y = true;
//Use a for loop and define the getters (with the object property's index as its "name") for each property using Object.defineProperty()
for (let i = 0; i < Object.keys(this).length; i++) {
Object.defineProperty(this, i, {
get: function() {
return Object.values(this)[i]}
});
}
}
}
var b = new className();
console.log(b[0]); // same as b.name ("Bikram")
console.log(b[1]); // = b.age (8)
console.log(b[2]); // = b.x (89)
console.log(b[3]); // = b.y (true)
Edit: If you want to change the properties by their indices, which, of course, you do. Then, just define a corresponding setter for each property in the Object.defineProperty() method. It will look like:
// Insert this in place of the old one
Object.defineProperty(this, i, {
get: function() {
return Object.values(this)[i];
},
set: function(newValue) {
this[Object.keys(this)[i]] = newValue;
}
})
console.log(b[0]); // "Bikram"
b[0] = "Bikram Kumar";
console.log(b[0]); // "Bikram Kumar"
And now you have an "array-like-object" whose properties can be accessed or modified either by property key or its index :D
A side note: Notice that Object.keys() and Object.values() only return the enumerable properties. If you just declare a property and not assign it to any value, the Object.[key/value]s() methods will leave that in the returned array, because by default they are not enumerable. This might become confusing for the indices so defined (except the case the undeclared property is the last one).
To get around this, there is a simple way, if you want some property to have a index, but don't wanna assign it now. Just set it to undefined, and it will now be enumerable, and the indices won't be affected.
by jquery you can do this:
var arr = $.map(obj,function(value, key) {
return value;
});
alert(obj[0]);
Get the array of keys, reverse it, then run your loop
var keys = Object.keys( obj ).reverse();
for(var i = 0; i < keys.length; i++){
var key = keys[i];
var value = obj[key];
//do stuff backwards
}
you can create an array that filled with your object fields and use an index on the array and access object properties via that
propertiesName:['pr1','pr2','pr3']
this.myObject[this.propertiesName[0]]
I went ahead and made a function for you:
Object.prototype.getValueByIndex = function (index) {
/*
Object.getOwnPropertyNames() takes in a parameter of the object,
and returns an array of all the properties.
In this case it would return: ["something","evenmore"].
So, this[Object.getOwnPropertyNames(this)[index]]; is really just the same thing as:
this[propertyName]
*/
return this[Object.getOwnPropertyNames(this)[index]];
};
let obj = {
'something' : 'awesome',
'evenmore' : 'crazy'
};
console.log(obj.getValueByIndex(0)); // Expected output: "awesome"
Sure it is possible, but it is not as immediate as accessing to an array by its indexes, but still possible and even relatively simple actually: in fact you don't have to struggle too much. This code sample will show how:
var obj = {
'alfa' : 'value of obj the key alfa',
'beta' : 'value of obj the key beta',
'gamma' : 'value of obj the key gamma'
};
var jbo = {
'alfa' : 'value of jbo the key alfa',
'beta' : 'value of jbo the key beta',
'gamma' : 'value of jbo the key gamma'
};
alert ( obj[Object.keys(obj)[1]] );
alert ( jbo[Object.keys(jbo)[1]] );
/* you can even put it into a for loop as follows */
for (i=0;i<3;i++)
{
document.writeln ( "<br>This could be even a piece of HTML: " + obj[Object.keys(obj)[i]] );
document.writeln ( "<br>This could be even a piece of HTML: " + jbo[Object.keys(jbo)[i]] );
}
Explication:
As you know the Object.keys() statement returns an array of all enumerable properties (which means all keys) of the object you type into its round parenthesis.
So the only thing you need is to indicate the index after that array, which will returns the key literal found at that index.
The key itself is "digested" as usual by the object which returns the value at that key.
If you are not sure Object.keys() is going to return you the keys in the right order, you can try this logic instead
var keys = []
var obj = {
'key1' : 'value1',
'key2' : 'value2',
'key3' : 'value3',
}
for (var key in obj){
keys.push(key)
}
console.log(obj[keys[1]])
console.log(obj[keys[2]])
console.log(obj[keys[3]])
You can also construct a function that will return the value of a property by accepting two parameters: the object and the "index" (order position)
function getValue(obj, index) {
let keysArray = Object.keys(obj)
let key = keysArray[index]
return obj[key]
}
Usage example getValue(obj, 2)
Snippet
let obj = {a: 'dog', b: 'cat', c: 'mouse'}
function getValue(obj, index){
let keysArray = Object.keys(obj)
let key = keysArray[index]
return obj[key]
}
console.log(getValue(obj, 2))

What is "import { obj, string } from 'grasshopper.data';"

There are many things I don't understand of my code:
I do not understand why the output prints "number"
What exactly do the obj and string in the import? (according to output)
Is there an alternative to use the import method? How could it be?
I am really sorry about fool question. I have studied only for two days.
import { obj, string } from 'grasshopper.data';
for (let i = 0; i < string.length; i++) {
let letter = string[i];
obj[letter] = i;
}
for (let property in obj) {
console.log(property + ': ' + obj[property]);
}
Below you can find the code's actual output:
h:0
o:1
n:2
e:3
s:4
t:5
g:0
a:1
t:2
h:3
e:4
r:5
w:0
a:1
t:2
e:3
r:4
j:0
u:1
i:2
c:3
e:4
import { obj, string } from 'grasshopper.data';
It means that you are getting the attributes 'obj' and 'string' from the object grasshopper.data.
JavaScript enables you to get just the attributes that you want from an object.
For example, suppose that I have the following object:
var myObj = {'name': "Foo Bar", 'nickname': "foo"}
And now I want to get just the nickname from myObj. To get that, I can use:
var {nickname} = myObj
That will give me "foo" as output.
You can also give a name for the variable that is created when you do that:
var {nickname: myVariable} = myObj
Now you have a variable called myVariable with myObj.nickname as value.
Hope this helped you :)

Accessing properties of a variable object with JavaScript

I have a js object that looks like this:
var object = {
"divisions": {
"ocd-division/country:us": {
"name": "United States",
}
}
};
I want to access the property listed under the nested object "ocd-division/country:us" (aka "name"), but the problem I'm having is that "ocd-division/country" is a variable object. Like it might be ":can" for Canada or something.
My question is, can I still access the name property under that object even though it's variable? I wrote the code I came up with below, but it calls the object literally, so it can't account for a change in the object's name.
var country = document.getElementById("p");
p.innerHTML = object.divisions["ocd-division/country:us"].name;
I'm new to JavaScript so I'm sorry if this is a dumb question.
When you don't know the properties of an object, you can use
for...in loop
It iterates enumerable own and enumerable inherited properties.
Object.keys
It returns an array which contains enumerable own properties.
Object.getOwnPropertyNames
It returns an array which contains own properties.
// Adding properties: "ownEnumerable", "ownNonEnumerable",
// "inheritedEnumerable" and "inheritedNonEnumerable"
var obj = Object.defineProperties({}, {
ownEnumerable: {enumerable: true},
ownNonEnumerable: {},
});
Object.defineProperties(Object.prototype, {
inheritedEnumerable: {enumerable: true},
inheritedNonEnumerable: {},
});
// Display results
function log(id, arr) {
document.getElementById(id).textContent = '[' + arr.join(', ') + ']';
}
log('forin', function(forInProps){
for (var prop in obj) forInProps.push(prop);
return forInProps;
}([]));
log('keys', Object.keys(obj));
log('names', Object.getOwnPropertyNames(obj));
<dl>
<dt><code>for...in</code></dt><dd id="forin"></dd>
<dt><code>Object.keys</code></dt><dd id="keys"></dd>
<dt><code>Object.getOwnPropertyNames</code></dt><dd id="names"></dd>
</dl>
object.divisions[Object.keys(object.divisions)[0]].name
Sure...
for (var division in object.divisions) {
var name = object.divisions[division].name;
// Do what you want with name here
}
If the object has prototype methods you will want to use Object.prototype.hasOwnProperty() to ensure they don't get iterated like so:
for (var division in object.divisions) {
if (!object.divisions.hasOwnProperty(division)) continue;
var name = object.divisions[division].name;
// Do what you want with name here
}
Or use Object.keys() if you don't care about IE8 support and iterate over those.
Object.keys(object.divisions).forEach(function(division) {
var name = object.divisions[division].name;
// Do what you want with name here
});
EDIT: Upon re-reading your question it occurs to me that you may already know the key name but want to access the object with a variable key name, which is also absolutely fine:
var division = 'ocd-division/country:us';
object.divisions[division].name;
When using [] bracket notation to access an object you can insert any code that evaluates to a string, you could even call a function in there that returns a string.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors
You can iterate through object using for loop.
var obj = {
"divisions":{
"ocd-division/country:us":{
"name" : "United States"
}
}
}
Here is the for loop
for(var a in obj){ //loop first the object
for(var b in obj[a]){ // then second object (divisions)
for(var c in obj[a][b]){ //then third object (ocd-division/country:us)
if(c == 'name'){ //c is the key of the object which is name
console.log(obj[a][b][c]); //print in console the value of name which is United States.
obj[a][b][c] = "Canada"; //replace the value of name.
var objName = obj[a][b][c]; //or pass it on variable.
}
}
}
}
console.log(obj); //name: Canada
console.log(objName); //name: United States
You can also use this reference:
https://developer.mozilla.org/enUS/docs/Web/JavaScript/Reference/Statements/for
http://stackoverflow.com/questions/8312459/iterate-through-object-properties

identifying object name by property value

I have an object for a given verb such as...
var schlafen = {
ger: "schlafen",
eng: "sleep",
stem: "schlaf",
pp: "geschlafen",
sp: "schlief",
type: "verb",
reflexive: false
};
I would like to be able to identify and reference the object and it's properties when my script comes across an instance of one of it's properties such as...
var example = "geschlafen";
I am trying to get to the object itself from only one of it's properties so that I can then use another one of it's properties(for example, the "type" property) to identify an instance of "geschlafen" as a verb.
One option would be to create an index object that maps the values back to the associated object, for example:
var index = {};
function indexObject(obj) {
var keys = ['ger', 'eng', 'stem', 'pp', 'sp'];
for (var i = 0; i < keys.length; i++) {
if (obj[keys[i]]) {
index[obj[keys[i]]] = obj;
}
}
}
// index your schlafen object (you would also want to do this for other objects)
indexObject(schlafen);
var example = "geschlafen";
// lookup the object using your index
var obj = index[example];
// make sure we got the correct object back (should log 'true')
console.log(obj === schlafen);

Getting the object's property name [duplicate]

This question already has answers here:
How to list the properties of a JavaScript object?
(18 answers)
Closed 6 months ago.
I was wondering if there was any way in JavaScript to loop through an object like so.
for(var i in myObject) {
// ...
}
But get the name of each property like this.
for(var i in myObject) {
separateObj[myObject[i].name] = myObject[i];
}
I can't seem to find anything like it on Google. They say to pass the names of the variables with them but this is not an option for what I am trying to achieve.
Thanks for any help you can offer.
Use Object.keys():
var myObject = { a: 'c', b: 'a', c: 'b' };
var keyNames = Object.keys(myObject);
console.log(keyNames); // Outputs ["a","b","c"]
Object.keys() gives you an array of property names belonging to the input object.
i is the name.
for(var name in obj) {
alert(name);
var value = obj[name];
alert(value);
}
So you could do:
seperateObj[i] = myObject[i];
Disclaimer
I misunderstood the question to be: "Can I know the property name that an object was attached to", but chose to leave the answer since some people may end up here while searching for that.
No, an object could be attached to multiple properties, so it has no way of knowing its name.
var obj = {a:1};
var a = {x: obj, y: obj}
What would obj's name be?
Are you sure you don't just want the property name from the for loop?
for (var propName in obj) {
console.log("Iterating through prop with name", propName, " its value is ", obj[propName])
}
you can easily iterate in objects
eg: if the object is
var a = {a:'apple', b:'ball', c:'cat', d:'doll', e:'elephant'};
Object.keys(a).forEach(key => {
console.log(key) // returns the keys in an object
console.log(a[key]) // returns the appropriate value
})
for direct access a object property by position...
generally usefull for property [0]... so it holds info about the further...
or in node.js 'require.cache[0]' for the first loaded external module, etc. etc.
Object.keys( myObject )[ 0 ]
Object.keys( myObject )[ 1 ]
...
Object.keys( myObject )[ n ]
Other than "Object.keys( obj )", we have very simple "for...in" loop - which loops over enumerable property names of an object.
const obj = {"fName":"John","lName":"Doe"};
for (const key in obj) {
//This will give key
console.log(key);
//This will give value
console.log(obj[key]);
}
To get the property of the object or the "array key" or "array index" depending on what your native language is..... Use the Object.keys() method.
Important, this is only compatible with "Modern browsers":
So if your object is called, myObject...
var c = 0;
for(c in myObject) {
console.log(Object.keys(myObject[c]));
}
Walla! This will definitely work in the latest firefox and ie11 and chrome...
Here is some documentation at MDN
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
IN ES5
E.G. you have this kind of object:
var ELEMENTS = {
STEP_ELEMENT: { ID: "0", imageName: "el_0.png" },
GREEN_ELEMENT: { ID: "1", imageName: "el_1.png" },
BLUE_ELEMENT: { ID: "2", imageName: "el_2.png" },
ORANGE_ELEMENT: { ID: "3", imageName: "el_3.png" },
PURPLE_ELEMENT: { ID: "4", imageName: "el_4.png" },
YELLOW_ELEMENT: { ID: "5", imageName: "el_5.png" }
};
And now if you want to have a function that if you pass '0' as a param - to get 'STEP_ELEMENT', if '2' to get 'BLUE_ELEMENT' and so for
function(elementId) {
var element = null;
Object.keys(ELEMENTS).forEach(function(key) {
if(ELEMENTS[key].ID === elementId.toString()){
element = key;
return;
}
});
return element;
}
This is probably not the best solution to the problem but its good to give you an idea how to do it.
Cheers.
As of 2018 , You can make use of Object.getOwnPropertyNames() as described in Developer Mozilla Documentation
const object1 = {
a: 1,
b: 2,
c: 3
};
console.log(Object.getOwnPropertyNames(object1));
// expected output: Array ["a", "b", "c"]
Using Object.keys() function for acquiring properties from an Object, and it can help search property by name, for example:
const Products = function(){
this.Product = "Product A";
this.Price = 9.99;
this.Quantity = 112;
};
// Simple find function case insensitive
let findPropByName = function(data, propertyName){
let props = [];
Object.keys(data).forEach(element => {
return props.push(element.toLowerCase());
});
console.log(props);
let i = props.indexOf(propertyName.toLowerCase());
if(i > -1){
return props[i];
}
return false;
};
// calling the function
let products = new Products();
console.log(findPropByName(products, 'quantity'));
When you do the for/in loop you put up first, i is the property name. So you have the property name, i, and access the value by doing myObject[i].
These solutions work too.
// Solution One
function removeProperty(obj, prop) {
var bool;
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
if (keys[i] === prop) {
delete obj[prop];
bool = true;
}
}
return Boolean(bool);
}
//Solution two
function removeProperty(obj, prop) {
var bool;
if (obj.hasOwnProperty(prop)) {
bool = true;
delete obj[prop];
}
return Boolean(bool);
}
Quick & dirty:
function getObjName(obj) {
return (wrap={obj}) && eval('for(p in obj){p}') && (wrap=null);
}

Categories

Resources