3

Taking the following example from: http://www.phpied.com/3-ways-to-define-a-javascript-class/

var apple = {
    type: "macintosh",
    color: "red",
    getInfo: function () {
        return this.color + ' ' + this.type + ' apple';
    }
};

Now I am moving the getInfo() method at the top of my object declaration.

var apple = {
    getInfo: function () {
        return this.color + ' ' + this.type + ' apple';
    },
    type: "macintosh",
    color: "red",
};

apple.getInfo();
red macintosh apple

I was expecting the javascript parser/compiler to fail, since this.color and this.type are not yet defined. How does this work internally ?

( this question was originally a ExtJS framework question here: ExtJS: settings properties via a function on the Prototype: is it a safe pattern?, but I realized it is a more general javascript question, hence this new one)

Community
  • 1
  • 1
Manu
  • 426
  • 3
  • 17
  • Once you call `apple.getInfo();` the whole apple object is already defined. – bumpy Aug 28 '15 at 10:59
  • Good question, well asked. – T.J. Crowder Aug 28 '15 at 11:02
  • The parser will not fail even if you added properties to this function that will never be defined. This is related to the fact that JavaScript is [https://en.wikipedia.org/wiki/Duck_typing](Duck Typed). – Sam Aug 28 '15 at 11:05
  • And as @hege_hegedus said, there should be a semicolon after the `}` on line 8. – Sam Aug 28 '15 at 11:07

3 Answers3

2

The function is called after you made the instance. When defined, it is not run, does not try to access the properties, but where you called the getInfo() function, they are all present. In fact, there is no way to run any custom JavaScript code between the interpreter parsing individual properties.

Andrea Dusza
  • 2,080
  • 3
  • 18
  • 28
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
2

The code inside the function is not executed until you call it, and so the property color of this is not evaluated until apple.getInfo() is called.

Edit:

var apple = {
    getInfo: function () {
        return this.color + ' ' + this.type + ' apple';
    },
    type: "macintosh",
    color: "red",
    }
}

At this time the apple object is defined, and the getInfo property is a function that will return the properties ``when it is evaluated

apple.getInfo();

The function is now evaluated, and the properties color and type have clearly already been defined at this point

The function obtains the values of these properties when it is evaluated so that if the properties color and type are changed, the return value of the function changes too.

Sam
  • 3,070
  • 3
  • 20
  • 26
  • 1
    "At this time the apple object is defined, and the getInfo property is a function that will return the properties when it is evaluated " This was the bit I was missing, thanks. – Manu Aug 28 '15 at 11:32
1

I was expecting the javascript parser/compiler to fail, since this.color and this.type are not yet defined.

The parser in the compiler doesn't care. JavaScript doesn't evaluate whether a property or variable can be found until the code using it is executed. And in the case of properties, a property that doesn't exist yet just gets created (if you're writing to it) or results in the value undefined (if you're reading from it), so even if your object didn't have color and type properties, the code still wouldn't throw an error. You'd just get the string "undefined undefined apple".

Javascript: when using Object literal, does ordering of properties matters?

Matters? Probably not. Have meaning? Yes, as of ES6 (aka ECMAScript 6 aka ECMAScript 20150), the latest specification. The order of properties in an object initializer determines the order the properties are created, which in turn partially sets the order in which they're visited by for-in loops, the order they show up in Object.keys arrays, etc. (Partially because property names that can coerce to integers are handled differently.) But it's rare for you to care. Details in this answer and this answer (that latter one is mostly about arrays, but touches on non-array objects as well).

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • "*which in turn sets the order in which they're visited by for-in loops*". Are you sure? I don't [*see it stated*](http://ecma-international.org/ecma-262/6.0/index.html#sec-for-in-and-for-of-statements), and [*Object.keys*](http://ecma-international.org/ecma-262/6.0/index.html#sec-object.keys) says "***If** an implementation defines a specific order of enumeration for the for-in statement…*" (my emphasis). The "if" is important. There are many references to "*in List order*" but nothing that defines the order of that list for Object properties (other than source order where obvious). – RobG Aug 28 '15 at 11:49
  • A bit confusing. The internal [*Enumerate* method says](http://ecma-international.org/ecma-262/6.0/index.html#sec-ordinary-object-internal-methods-and-internal-slots-enumerate) "*The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below*", then [*OwnPropertyKeys*]() says "*…in property creation order…*". Guess I've talked myself out of it. Or into it. Whatever. – RobG Aug 28 '15 at 11:58
  • @RobG: Yup, I'm sure. So many engines were doing it (but slightly differently from one another vis-a-vis index-style properties vs. non-index-style properties) that they decided to specify it. I'll see if I can track down my answer where I got out my machete and worked through the spec to figure out if it was really true. :-) – T.J. Crowder Aug 28 '15 at 12:02
  • @RobG: Added links to the answer which are other answers where I documented my hacking through the spec. – T.J. Crowder Aug 28 '15 at 12:07
  • Thanks, it's still a mess though, as numeric keys are always first and always in numeric order, regardless of when they were added (in ECMAScript 2015 compliant implementations) and I still don't get the "if" for *Object.keys*. Perhaps it could be fixed if Arrays and Objects were completely separate objects, but the property enumeration rules seem to be trying to suit both without really suiting either. – RobG Aug 28 '15 at 12:29
  • @RobG: It's less of a mess than we had before, where people relied on order even though it was unreliable. :-) Re "if" on Object.keys, you mean *"If an implementation defines a specific order of enumeration for the for-in statement, the same order must be used for the elements of the array returned in step 4."*? Yeah, that has to be a bug (it's in the final spec, too), a holdover from ES5 (same "if", slightly different wording). Or it could be referring to host objects (not JavaScript objects). – T.J. Crowder Aug 28 '15 at 12:34