JavaScript - Iterating through objects in instance of object 'class' - javascript

I'm trying to iterate through all objects inside the instance of an object using pure JavaScript.
I tried something like this:
function a(){
this.iterate = function(){
for (var obj in this){
console.log(obj);
}
}
}
var A = new a();
A.insertedValue = 20;
A.iterate();
When doing this, instead of logging for example "20" for insertedValue it simply logs the name of the variable like "insertedValue".
Is there either a better way of looping through all objects in an instance of a object or a way to get the values from the objects I'm looping through?

Is there either a better way of looping trough all objects in an
instance of a object or a way to get the values from the objects I'm
looping trough?
Because you are simply printing the key inside this rather than its value using this[obj].
Make it
function a(){
this.iterate = function(){
for (var obj in this){
console.log(this[obj]); //observe that this line has changed
}
}
}

The way you're doing it is largely correct, it's just that for-in loops through the names of the object's properties, not their values. So to output the property's value, you use this[name]:
function a(){
this.iterate = function(){
for (var name in this){
console.log(name + "=" + this[name]);
}
};
}
Note that for-in will loop through the enumerable properties of the object, including ones it inherits from its prototype. If you just want own properties, and not inherited ones, you can either check whether the property is an "own" property through hasOwnProperty:
function a(){
this.iterate = function(){
for (var name in this){
if (this.hasOwnProperty(name)) {
console.log(name + "=" + this[name]);
}
}
};
}
Or use the handy Object.keys, which gives you an array of own enumerable properties:
function a(){
this.iterate = function(){
Object.keys(this).forEach(function(name) {
console.log(name + "=" + this[name]);
});
};
}

Related

How to slice() return values from JSON API [duplicate]

var obj = {
name: "Simon",
age: "20",
clothing: {
style: "simple",
hipster: false
}
}
for(var propt in obj){
console.log(propt + ': ' + obj[propt]);
}
How does the variable propt represent the properties of the object? It's not a built-in method or property. Why does it come up with every property in the object?
Iterating over properties requires this additional hasOwnProperty check:
for (var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
// do stuff
}
}
It's necessary because an object's prototype contains additional properties for the object which are technically part of the object. These additional properties are inherited from the base object class, but are still properties of obj.
hasOwnProperty simply checks to see if this is a property specific to this class, and not one inherited from the base class.
It's also possible to call hasOwnProperty through the object itself:
if (obj.hasOwnProperty(prop)) {
// do stuff
}
But this will fail if the object has an unrelated field with the same name:
var obj = { foo: 42, hasOwnProperty: 'lol' };
obj.hasOwnProperty('foo'); // TypeError: hasOwnProperty is not a function
That's why it's safer to call it through Object.prototype instead:
var obj = { foo: 42, hasOwnProperty: 'lol' };
Object.prototype.hasOwnProperty.call(obj, 'foo'); // true
As of JavaScript 1.8.5 you can use Object.keys(obj) to get an Array of properties defined on the object itself (the ones that return true for obj.hasOwnProperty(key)).
Object.keys(obj).forEach(function(key,index) {
// key: the name of the object key
// index: the ordinal position of the key within the object
});
This is better (and more readable) than using a for-in loop.
Its supported on these browsers:
Firefox (Gecko): 4 (2.0)
Chrome: 5
Internet Explorer: 9
See the Mozilla Developer Network Object.keys()'s reference for futher information.
Girls and guys we are in 2019 and we do not have that much time for typing... So lets do this cool new fancy ECMAScript 2016:
Object.keys(obj).forEach(e => console.log(`key=${e} value=${obj[e]}`));
In up-to-date implementations of ES, you can use Object.entries:
for (const [key, value] of Object.entries(obj)) { }
or
Object.entries(obj).forEach(([key, value]) => ...)
If you just want to iterate over the values, then use Object.values:
for (const value of Object.values(obj)) { }
or
Object.values(obj).forEach(value => ...)
It's the for...in statement (MDN, ECMAScript spec).
You can read it as "FOR every property IN the obj object, assign each property to the PROPT variable in turn".
It's just a for...in loop. Check out the documentation at Mozilla.
if (typeof obj === 'object' && obj !== null) {
Object.keys(obj).forEach(key => {
console.log("\n" + key + ": " + obj[key]);
});
}
// *** Explanation line by line ***
// Explaining the bellow line
// It checks if obj is neither null nor undefined, which means it's safe to get its keys.
// Otherwise it will give you a "TypeError: Cannot convert undefined or null to object" if obj is null or undefined.
// NOTE 1: You can use Object.hasOwnProperty() instead of Object.keys(obj).length
// NOTE 2: No need to check if obj is an array because it will work just fine.
// NOTE 3: No need to check if obj is a string because it will not pass the 'if typeof obj is Object' statement.
// NOTE 4: No need to check if Obj is undefined because it will not pass the 'if type obj is Object' statement either.
if (typeof obj === 'object' && obj !== null) {
// Explaining the bellow line
// Just like in the previous line, this returns an array with
// all keys in obj (because if code execution got here, it means
// obj has keys.)
// Then just invoke built-in javascript forEach() to loop
// over each key in returned array and calls a call back function
// on each array element (key), using ES6 arrow function (=>)
// Or you can just use a normal function ((key) { blah blah }).
Object.keys(obj).forEach(key => {
// The bellow line prints out all keys with their
// respective value in obj.
// key comes from the returned array in Object.keys(obj)
// obj[key] returns the value of key in obj
console.log("\n" + key + ": " + obj[key]);
});
}
If your environment supports ES2017 then I would recommend Object.entries:
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`);
});
As shown in Mozillas Object.entries() documentation:
The Object.entries() method returns an array of a given object's own
enumerable property [key, value] pairs, in the same order as that
provided by a for...in loop (the difference being that a for-in loop
enumerates properties in the prototype chain as well).
Basically with Object.entries we can forgo the following extra step that is required with the older for...in loop:
// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
// do stuff
}
Dominik's answer is perfect, I just prefer to do it that way, as it's cleaner to read:
for (var property in obj) {
if (!obj.hasOwnProperty(property)) continue;
// Do stuff...
}
jquery allows you to do this now:
$.each( obj, function( key, value ) {
alert( key + ": " + value );
});
The for...in loop represents each property in an object because it is just like a for loop. You defined propt in the for...in loop by doing:
for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}
A for...in loop iterates through the enumerable properties of an object. Whichever variable you define, or put in the for...in loop, changes each time it goes to the next property it iterates. The variable in the for...in loop iterates through the keys, but the value of it is the key's value. For example:
for(var propt in obj) {
console.log(propt);//logs name
console.log(obj[propt]);//logs "Simon"
}
You can see how the variable differs from the variable's value. In contrast, a for...of loop does the opposite.
I hope this helps.
To add ES2015's usage of Reflect.ownKeys(obj) and also iterating over the properties via an iterator.
For example:
let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } };
can be iterated over by
// logs each key
Reflect.ownKeys(obj).forEach(key => console.log(key));
If you would like to iterate directly over the values of the keys of an object, you can define an iterator, just like JavaScipts's default iterators for strings, arrays, typed arrays, Map and Set.
JS will attempt to iterate via the default iterator property, which must be defined as Symbol.iterator.
If you want to be able to iterate over all objects you can add it as a prototype of Object:
Object.prototype[Symbol.iterator] = function*() {
for(p of Reflect.ownKeys(this)){ yield this[p]; }
}
This would enable you to iterate over the values of an object with a for...of loop, for example:
for(val of obj) { console.log('Value is:' + val ) }
Caution: As of writing this answer (June 2018) all other browsers, but IE, support generators and for...of iteration via Symbol.iterator
The above answers are a bit annoying because they don't explain what you do inside the for loop after you ensure it's an object: YOU DON'T ACCESS IT DIRECTLY! You are actually only delivered the KEY that you need to apply to the OBJ:
var obj = {
a: "foo",
b: "bar",
c: "foobar"
};
// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
// We check if this key exists in the obj
if (obj.hasOwnProperty(someKey))
{
// someKey is only the KEY (string)! Use it to get the obj:
var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"
// NOW you can treat it like an obj
var shouldBeBar = myActualPropFromObj.b;
}
}
This is all ECMA5 safe. Even works in the lame JS versions like Rhino ;)
let obj = {"a": 3, "b": 2, "6": "a"}
Object.keys(obj).forEach((item) => {console.log("item", obj[item])})
// a
// 3
// 2
You can access the nested properties of the object using the for...in and forEach loop.
for...in:
for (const key in info) {
console.log(info[key]);
}
forEach:
Object.keys(info).forEach(function(prop) {
console.log(info[prop]);
// cities: Array[3], continent: "North America", images: Array[3], name: "Canada"
// "prop" is the property name
// "data[prop]" is the property value
});
You can use Lodash. The documentation
var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
...
});
Object.keys(obj).forEach(key =>
console.log(`key=${key} value=${obj[key]}`)
);
Nowadays you can convert a standard JS object into an iterable object just by adding a Symbol.iterator method. Then you can use a for of loop and acceess its values directly or even can use a spread operator on the object too. Cool. Let's see how we can make it:
var o = {a:1,b:2,c:3},
a = [];
o[Symbol.iterator] = function*(){
var ok = Object.keys(this);
i = 0;
while (i < ok.length) yield this[ok[i++]];
};
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);
Your for loop is iterating over all of the properties of the object obj. propt is defined in the first line of your for loop. It is a string that is a name of a property of the obj object. In the first iteration of the loop, propt would be "name".
Objects in JavaScript are collections of properties and can therefore be looped in a for each statement.
You should think of obj as an key value collection.
If running Node I'd recommend:
Object.keys(obj).forEach((key, index) => {
console.log(key);
});
While the top-rated answer is correct, here is an alternate use case i.e if you are iterating over an object and want to create an array in the end. Use .map instead of forEach
const newObj = Object.keys(obj).map(el => {
//ell will hold keys
// Getting the value of the keys should be as simple as obj[el]
})
I want to add to the answers above, because you might have different intentions from Javascript. A JSON object and a Javascript object are different things, and you might want to iterate through the properties of a JSON object using the solutions proposed above, and then be surprised.
Suppose that you have a JSON object like:
var example = {
"prop1": "value1",
"prop2": [ "value2_0", "value2_1"],
"prop3": {
"prop3_1": "value3_1"
}
}
The wrong way to iterate through its 'properties':
function recursivelyIterateProperties(jsonObject) {
for (var prop in Object.keys(example)) {
console.log(prop);
recursivelyIterateProperties(jsonObject[prop]);
}
}
You might be surprised of seeing the console logging 0, 1, etc. when iterating through the properties of prop1 and prop2 and of prop3_1. Those objects are sequences, and the indexes of a sequence are properties of that object in Javascript.
A better way to recursively iterate through a JSON object properties would be to first check if that object is a sequence or not:
function recursivelyIterateProperties(jsonObject) {
for (var prop in Object.keys(example)) {
console.log(prop);
if (!(typeof(jsonObject[prop]) === 'string')
&& !(jsonObject[prop] instanceof Array)) {
recursivelyIterateProperties(jsonObject[prop]);
}
}
}
What for..in loop does is that it creates a new variable (var someVariable) and then stores each property of the given object in this new variable(someVariable) one by one. Therefore if you use block {}, you can iterate. Consider the following example.
var obj = {
name:'raman',
hobby:'coding',
planet:'earth'
};
for(var someVariable in obj) {
//do nothing..
}
console.log(someVariable); // outputs planet
Here I am iterating each node and creating meaningful node names. If you notice, instanceOf Array and instanceOf Object pretty much does the same thing (in my application, i am giving different logic though)
function iterate(obj,parent_node) {
parent_node = parent_node || '';
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
var node = parent_node + "/" + property;
if(obj[property] instanceof Array) {
//console.log('array: ' + node + ":" + obj[property]);
iterate(obj[property],node)
} else if(obj[property] instanceof Object){
//console.log('Object: ' + node + ":" + obj[property]);
iterate(obj[property],node)
}
else {
console.log(node + ":" + obj[property]);
}
}
}
}
note - I am inspired by Ondrej Svejdar's answer. But this solution has better performance and less ambiguous
Also adding the recursive way:
function iterate(obj) {
// watch for objects we've already iterated so we won't end in endless cycle
// for cases like var foo = {}; foo.bar = foo; iterate(foo);
var walked = [];
var stack = [{obj: obj, stack: ''}];
while(stack.length > 0)
{
var item = stack.pop();
var obj = item.obj;
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
// check if we haven't iterated through the reference yet
var alreadyFound = false;
for(var i = 0; i < walked.length; i++)
{
if (walked[i] === obj[property])
{
alreadyFound = true;
break;
}
}
// new object reference
if (!alreadyFound)
{
walked.push(obj[property]);
stack.push({obj: obj[property], stack: item.stack + '.' + property});
}
}
else
{
console.log(item.stack + '.' + property + "=" + obj[property]);
}
}
}
}
}
Usage:
iterate({ foo: "foo", bar: { foo: "foo"} });
You basically want to loop through each property in the object.
JSFiddle
var Dictionary = {
If: {
you: {
can: '',
make: ''
},
sense: ''
},
of: {
the: {
sentence: {
it: '',
worked: ''
}
}
}
};
function Iterate(obj) {
for (prop in obj) {
if (obj.hasOwnProperty(prop) && isNaN(prop)) {
console.log(prop + ': ' + obj[prop]);
Iterate(obj[prop]);
}
}
}
Iterate(Dictionary);
To further refine the accepted answer it's worth noting that if you instantiate the object with a var object = Object.create(null) then object.hasOwnProperty(property) will trigger a TypeError. So to be on the safe side, you'd need to call it from the prototype like this:
for (var property in object) {
if (Object.prototype.hasOwnProperty.call(object, property)) {
// do stuff
}
}
Check type
You can check how propt represent object propertis by
typeof propt
to discover that it's just a string (name of property). It come up with every property in the object due the way of how for-in js "build-in" loop works.
var obj = {
name: "Simon",
age: "20",
clothing: {
style: "simple",
hipster: false
}
}
for(var propt in obj){
console.log(typeof propt, propt + ': ' + obj[propt]);
}
If you just want to iterate to map property values then lodash has _.mapValues
const obj = {
a: 2,
b: 3
}
const res = _.mapValues(obj, v => v * 2)
console.log(res)
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>

get all methods and properties of an object

If I use (on a text frame):
b.selection().fit(FitOptions.frameToContent);
Then it works as expected, this means that the selected object has a fit method.
If I use:
for (var property in b.selection()) {
b.println(property);
}
On the same selection then it doesn't print a fit method.
If I use this:
function getMethods(obj) {
var result = [];
for (var id in obj) {
try {
if (typeof(obj[id]) == "function") {
result.push(id + ": " + obj[id].toString());
}
} catch (err) {
result.push(id + ": inaccessible");
}
}
return result;
}
b.println(getMethods(b.selection()));
Then I don't get the fit method either. And I would really like to know all methods and properties of the selected object. So how do i get them?
try obj.reflect.methods to get all methods
When method fit() exists and doesn't shine up in the for-in-loop it is a non-enumerable property.
There are different ways to access the properties of an object:
var obj = b.selection();
for (var p in obj) {
console.log(p); // --> all enumerable properties of obj AND its prototype
}
Object.keys(obj).forEach(function(p) {
console.log(p); // --> all enumerable OWN properties of obj, NOT of its prototype
});
Object.getOwnPropertyNames(obj).forEach(function(p) {
console.log(p); // all enumerable AND non-enumerable OWN properties of obj, NOT of its prototype
});
If you don't find .fit() on one of this ways its not enumerable AND not OWN property of obj, but sits somewhere in the prototype of obj. Then you can do:
var prot = Object.getPrototypeOf(obj);
Object.getOwnPropertyNames(prot).forEach(function(pp) {
console.log(pp); // --> all enumerable AND non-enumerable properties of obj's prototype
});
Often objects have a bit longer prototype-chain and the property sits somewhere deeper on it. Then you just repeat the last snippet as often as needed:
var prot2 = Object.getPrototypeOf(prot);
Object.getOwnPropertyNames(prot2).forEach( /*...*/ );
To make it complete: Let's say you have found .fit on the obj's prototype prot. Then you can inspect it:
console.log(Object.getOwnPropertyDescriptor(prot.fit));
That outputs an object which shows the value of prot.fit and whether it's enumerable, writable, and configurable or not. The Object.methods and some more FIND HERE.
Or just use b.inspect(obj). Prints out all properties and values of an object in a recursive manner to the console. See http://basiljs.ch/reference/#inspect

Issue finding all variables in an Object

I have an Object called Button_Objs, its purpose is to hold all my Button Objects. I made a function in my Button_Objs which iterates through each of its variables. Here is where the issue is, I have a if statement that says: if (i typeof Button){}. I do this so it only selects the Button Objects that are stored.
Here is the JSFiddle of this: http://jsfiddle.net/MichaelMitchell/vcZTR/15/
var Button_Objs = function() {
this.getButtons = function() {
var i;
for (i in this) {
if (type of i == Button) { //PROBLEM, also does not work with instanceof.
document.getElementById('console').innerHTML += ( "button: " + i + "<br />");
}
}
};
};
I also tried instanceof, but alas it will not work :(
i typeof Button is invalid syntax and type of i == Button as well.
When you use a for...in loop to iterate over an object, the loop variable will hold the name of the property, not the value. You can use the name to get the value:
if(this[i] instanceof Button)
Read more about the for...in loop (I recommend to have a look at MDN to learn about JS basics).
Apart from this, I don't see why you need a constructor function to create a container for your buttons. You could just use a plain object:
var buttons = {};
// somewhere
buttons['button' + i] = new Button(...);
and then again use the for...in loop to iterate over the object.
And if you don't actually need the names (they just seem to be some sort of enumeration), why don't you use an array?
var buttons = [];
// somewhere
buttons.push(new Button(...));
and then use a for loop to iterate over all buttons. You would not even have to test for their type.

hasOwnProperty in JavaScript

Consider:
function Shape() {
this.name = "Generic";
this.draw = function() {
return "Drawing " + this.name + " Shape";
};
}
function welcomeMessage()
{
var shape1 = new Shape();
//alert(shape1.draw());
alert(shape1.hasOwnProperty(name)); // This is returning false
}
.welcomeMessage called on the body.onload event.
I expected shape1.hasOwnProperty(name) to return true, but it's returning false.
What is the correct behavior?
hasOwnProperty is a normal JavaScript function that takes a string argument.
When you call shape1.hasOwnProperty(name) you are passing it the value of the name variable (which doesn't exist), just as it would if you wrote alert(name).
You need to call hasOwnProperty with a string containing name, like this: shape1.hasOwnProperty("name").
hasOwnProperty expects the property name as a string, so it would be shape1.hasOwnProperty("name")
Try this:
function welcomeMessage()
{
var shape1 = new Shape();
//alert(shape1.draw());
alert(shape1.hasOwnProperty("name"));
}
When working with reflection in JavaScript, member objects are always refered to as the name as a string. For example:
for(i in obj) { ... }
The loop iterator i will be hold a string value with the name of the property. To use that in code you have to address the property using the array operator like this:
for(i in obj) {
alert("The value of obj." + i + " = " + obj[i]);
}
hasOwnProperty() is a nice property to validate object keys.
Example:
var obj = {a:1, b:2};
obj.hasOwnProperty('a') // true

Remove element from Javascript associative array using array value

I am trying to remove an element from a Javascript associtive array using the value to find it, but I am having trouble. I have tried splice and JQuery's grep method and neither have worked for me. This is what I currently have.
var array_path = new Array();
function bulk_upload(){
var temp_array = new Object();
for (var i = 1; i<8; i++){
temp_array[i] = $('#path' + i).val();
if(temp_array[i]!='' && temp_array[i]!=null){
array_path['path' + i] = $('#path' + i).val();
}
}
process_txt();
}
function process_txt(){
//alert(array_path.indexOf(full_path)); //returns nothing
var removed_element = array_path.splice(getKey(array_path), 1);
//array_path = $.grep(array_path, function(val) { return val != full_path; });
alert(removed_element);//return nothing, just blank alert box
}
function getKey(data) {
for (var prop in data)
return prop;
}
The way to do this is to use the delete operator.
delete array_path[getKey(array_path)]
Some Background Information
In JavaScript, almost everything descends from Object.prototype. JavaScript, being an open and dynamic language allows you to create/modify properties of objects by simple assignment. This is very similar to what an associative array -- a structure that contains keyed values.
Under the hood an array is just an object that descends from Array.prototype with numeric keys and a special property called length. The length property just returns one greater than the highest numeric property. In essence, an Array is an object with different semantics.
If you're wanting an associative array then Array is not the object you want to descend from. You would want to descend directly from Object. There are two ways to do that, you could either use the new operator or an empty object literal. The syntax for both is below:
var o = new Object();
var o = {};
The second is preferred since it's a little bit more concise.
I wrote a blog post about this a while back, have a look if you want a little bit more info.
There is no such thing in JavaScript as an "associative array" per se. The data structure which corresponds to this concept is simply a JavaScript Object.
Of course, a JavaScript Array (like essentially everything in JavaScript) is an Object, but one with additional capabilities. So you can use an Array as a key-value map, but it's really not the correct structure for that.
To remove a key from an Object, you just do something like this:
var myObj = {};
var myKey = "blah";
myObj[myKey] = 1234; // Adds or updates value for "blah" to 1234.
delete myObj[myKey]; // Removes key-value pair for "blah".
Have you tried delete hash.someKey; ?
You can give your object a remove method, or use apply or call to use another object's remove method, if defined.
function myObj(members){
for(var p in members) this[p]= members[p];
}
myObj.prototype.remove= function(val){
for(var p in this){
if(this[p]=== val) delete this[p];
}
return this;
}
myObj.prototype.toString= function(){
var A= [];;
for(var p in this){
if(this.hasOwnProperty(p)){
A.push(p+':'+this[p])
}
}
return '{'+A.join(', ')+'}';
}
var O= new myObj({a: 1, b: 10, c: 100});
alert(O)
O.remove(10);
alert(O)
I'm not psychic, so I can only guess that you wanted to accomplish something like this:
var paths = [];
function getPaths() {
for(var i = 1; i < 8; ++i) {
var value = $('#path' + i).val();
if(value) paths.push(value);
}
}
function process() {
var firstPath = paths.shift();
// do stuff
}
getPaths();
if(paths.length) process();

Categories