0

What kind of magic is that, when you Object.keys() on an object with one key only, it will be treated as a string when you reference later using square brackets?

See below for example:

let chosenProducts = [
  {
    toys: 20
  }  
];

let toys = "toys";

chosenProducts.forEach(product => {
  let name = Object.keys(product);

  console.log(Array.isArray(name)); // true
  console.log(name) // ['toys']
  console.log(toys) // "toys" - string
  console.log(product[name]); // 20 - array used = wtf?
  console.log(product[toys]); // 20 - string used

});
1
  • 1
    It's nothing magic about the array having only one element in it. Exactly the same thing happens if it has two or even more: jsfiddle.net/tjcrowder/L9vp7rhn It's just less likely to match a property in the object. (I've made it do so, by slipping non-enumerable properties into the object so their names don't appear in the array from Object.keys.) Commented Nov 8, 2019 at 11:20

2 Answers 2

3

Object.keys returns an array.

All objects have a toString method.

If you use an object in string context, toString is called implicitly.

Square-bracket property accessor notation is, essentially, string context (unless you pass a Symbol)

The default toString method on an array looks something like: function () { return this.join(","); }

const example1 = ["foo", "bar"];
console.log("" + example1);

const example2 = ["baz"];
console.log("" + example2);

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

Comments

1

Object.keys returns an array of keys. Your name variable is an array with one element ['toys']. When you access product[name] implicit coercion of name array to string happens which results in product["toys"]

In javascript there are two types of coercions implicit and explicit coercion

When you access with Object's properties they will be string, in case of an array they will be indexes (numbers), but array is also an object, when you add any property in array it can be act as object property(string) and will not get counted towards the length of array.

let arr = [1,3];
arr.val = 20;
console.log(arr.length); // 2

In your example you are accessing object's property product[name] here name is an array. What will happen here is implicit coercion of array to string. Javascript will automatically call toString method on your object which is an array in this case. There is toString method for Array which is linked to their prototype Array.prototype.toString. You can override that if you want to get different result.

In simple terms when you try to access variable in if conditional expression javascript automatically coerce to Boolean value.

let a = 10;
if(a){
    console.log("implicit coercion");
}

if(Boolean(a)){
    console.log("explicit coercion");
}

To learn more about Javascript grammar and types.

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.