1

I am currently going through Eloquent Javascript and this is a question about properties and usage of strings in those properties.

I am looking at two objects in chapter 4:

http://eloquentjavascript.net/code/jacques_journal.js

and

var journal = [
  {events: ["work", "touched tree", "pizza",
            "running", "television"],
   squirrel: false},
  {events: ["work", "ice cream", "cauliflower",
            "lasagna", "touched tree", "brushed teeth"],
   squirrel: false},
  {events: ["weekend", "cycling", "break",
            "peanuts", "beer"],
   squirrel: true},
  /* and so on... */
];

question: Do the property names need to be strings like in the Jacques Journal object? OR can they can just be listed as events and squirrel in the above object?

In either case, will this code still work:

function tableFor(event, journal) {
return journal.events.indexOf(event)
}

tableFor("pizza", JOURNAL)    (notice that the JOURNAL object is found within the link provided)

What does everyone use to test Javascript code with lots of indentation? I tried using the Dev tools in chrome but it's annoying to have to manually type in indentation with the space bar. Can you test javascript code in Sublime Text?

Jwan622
  • 11,015
  • 21
  • 88
  • 181
  • I'm not sure what you're actually asking, but there's not `journal.events` in `journal` array, hence `tableFor` function will trigger a Reference error. Notice, that `journal` is not an object, it's an array. When referring to the members of an array, you use indices, not property names. – Teemu Oct 10 '14 at 20:45
  • 1
    +1 just because you didn't call JS array as JSON object ; ). – Teemu Oct 10 '14 at 20:55
  • I'm looking up the difference now. – Jwan622 Oct 11 '14 at 17:56

2 Answers2

3
var foo = { "bar": 123 };
var foo = { bar: 123 };

The above two lines of JavaScript are exactly equivalent. In either case you can access the "bar" property in two different ways:

console.log( foo.bar );     # => 123
console.log( foo["bar"] );  # => 123

You only need to use the quotation mark syntax ({ "bar": 123 }) when the key isn't a valid JavaScript identifier. To quote MDN:

A JavaScript identifier must start with a letter, underscore (_), or dollar sign ($); subsequent characters can also be digits (0-9). Because JavaScript is case sensitive, letters include the characters "A" through "Z" (uppercase) and the characters "a" through "z" (lowercase).

Starting with JavaScript 1.5, you can use ISO 8859-1 or Unicode letters such as å and ü in identifiers. You can also use the \uXXXX Unicode escape sequences as characters in identifiers.

For example, this is valid:

var obj = { "": 1,
            "!": 2,
            "foo bar": 3,
            "99bottles": 4 }

But without the quotation marks, any of those would throw an error.

There's one other time when quotation marks are necessary, and that's when you want to use a key that's a reserved word in JavaScript, like return or else or class. Sometimes you can do it just fine:

var obj = { else: 123 }
console.log( obj.else ) # => 123

...but this depends on the JavaScript parser being able to tell that you're using it as a property name and not as a keyword. If, for example, you open up your JavaScript console right now and type:

{ else: 123 }

...you'll get a SyntaxError. So, when it comes to words that have special meaning in JavaScript (there's a full list here), it's best to use quotation marks:

var obj = { "else": 123 }

On the other side of the coin—which is to say, getting things out of the object you've created—the story is much the same. Suppose we have this object:

var obj = { foo: 1,  // note that we can mix quoted and non-quoted if we want
            "": 2,
            "99bottles": 3,
            "else": 4,
            "foo bar": 5,
            $gt: 6 }

For keys that are valid identifiers, we can use regular "dot notation" to access the properties, but for the others we have to use "bracket notation":

obj.foo          # => 1
obj[""]          # => 2
obj.99bottles    # => SyntaxError: Unexpected token ILLEGAL
obj["99bottles"] # => 3
obj.else         # => 4
obj["foo bar"]   # => 5
obj.$gt          # => 6

Finally, it's worth noting that JSON is a subset of JavaScript. This is valid JavaScript, but it's not a valid JSON object:

{ foo: "bar" }

Quotation marks are required around JSON property names. The below is valid JSON:

{ "foo": "bar" }
Jordan Running
  • 102,619
  • 17
  • 182
  • 182
1

First of all your your last snippet will throw following error:

Uncaught TypeError: Cannot read property 'indexOf' of undefined

This is right because there is no element with value "pizza" in your journal array. You have just some json objects in your array. So you have to iterate through all objects to find out the value of property squirrel.

Something like this will work:

function tableFor(event, journal) {
    for(var i=0;i<journal.length;i++){
      if(journal[i].events.indexOf(event) > 0) return journal[i].squirrel;
    }
    return false;
}

Keep in mind that everything in javascript is an object, so you can "abuse" an Array object by setting arbitrary properties on it. Use Arrays for numerically indexed data and objects for non-numeric keys.

More information in this stackoverflow post

There are many ways to test your javascript... You can do it online (jsfiddle for example) or in your console in browser.

Community
  • 1
  • 1
Sven Schürmann
  • 602
  • 3
  • 4