0

I am creating a JavaScript object and assigning a key which is dynamic. So there may be white space in the key. I can see the object in the browser console as follows,

{barTitle: 'Cash Flow', Cash Flow: 90254}

When I am looping through the object as follows,

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

I'm getting the following result,

barTitle Alrais
undefined

in browser console. How can I access the key in the above case (Please note that the object is dynamic and I don't know the key. In case if know the key then I can access it like obj['Cash Flow']) ?

9
  • 1
    Wrap the key of your object in '', like this: 'Cash Flow' : 90254 Commented Aug 7, 2017 at 10:01
  • You'll have to add a minimal reproducible example to your question demonstrating the problem, ideally a runnable one using Stack Snippets (the [<>] toolbar button). There's no reason that the property should be undefined assuming the object is actually correctly created: jsfiddle.net/txxj7fhx Commented Aug 7, 2017 at 10:01
  • @Patrick2607: The OP clearly said that's just what's showing in the browser console (not an actual object initializer). Commented Aug 7, 2017 at 10:02
  • 1
    I'm pretty sure there was an exception thrown when you're trying to create the object. This should not be possible. oO Commented Aug 7, 2017 at 10:05
  • JS objects have keys and values. Keys are strings. So do it this way: {"barTitle": "Cash Flow", "Cash Flow": 90254} Commented Aug 7, 2017 at 10:05

1 Answer 1

1

Three possibilities here:

  1. The "Cash Flow" property is inherited, or

  2. The "Cash Flow" property is non-enumerable, or

  3. Both. :-)

Object.keys only gives you the names of the enumerable, own properties of an object. Both inherited and non-enumerable ones are skipped.

You can use for-in to access all enumerable properties, including inherited ones:

var proto = {"Cash Flow": 90254};
var obj = Object.create(proto);
obj.barTitle = 'Cash Flow';

// Doesn't show
Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});
console.log("----");

// Shows:
for (var key in obj) {
    console.log(key, obj[key]);
}

You can use Object.getOwnPropertyNames to get all "own" properties of an object, including non-enumerable ones (this was new in ES5 [2009]):

var obj = {barTitle: "Cash Flow"};
Object.defineProperty(obj, "Cash Flow", {
  value: 90254
});

// Doesn't show
Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});
console.log("----");

// Shows:
Object.getOwnPropertyNames(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

If you need all properties with String names, including inherited non-enumerable ones, you can easily combine Object.getOwnPropertyNames with Object.getPrototypeOf (new in ES2015) to build a loop:

var proto = {};
Object.defineProperty(proto, "Cash Flow", {
  value: 90254
});
var obj = Object.create(proto);
obj.barTitle = "Cash Flow";

// Doesn't show
Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});
console.log("----");

// Shows:
getAllPropertyNames(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

function getAllPropertyNames(obj) {
  var names = Object.create(null);
  var p = obj;
  while (p && p !== Object.prototype) {
    Object.getOwnPropertyNames(p).forEach(function(name) {
     names[name] = true;
    });
    p = Object.getPrototypeOf(p);
  }
  return Object.keys(names);
}

In that, I've assumed you don't want to see the properties of Object.prototype, so we stop early if it's in the prototype chain of the object.

Also note that I've assumed you aren't interested in Symbol-named properties. If you are, use Object.getOwnPropertySymbols to access them.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.