Loading ...
Sorry, an error occurred while loading the content.

41935Re: Execution Scope and Functions/Objects/Classes/etc

Expand Messages
  • Michael Hasenstein
    Dec 4, 2008
      Hi,

      (A reply for the previous poster, and maybe others, actually. Because I'm having a lot of fun exploring the details of Javascript right now myself and explaining them to others - one learns most oneself by teaching others :-)   If you don't need the explanation, please excuse me. Maybe someone will.)

      Well, it isn't exactly the same. Okay, for all practical purposes the particular examples (repeated below) indeed ARE equivalent. But let me extend the example a little to show the difference.

      Instead of using an anonymous function expression (as in
      YAHOO.au.com.company.SomeWidget = new function(){...) I'm going to assign a function expression to a variable (I could also use a so-called function declaration, which would be  "function name () {...}" used at the top level, i.e. not nested into something else, but I prefer to assign functions to variables. The subtle difference is that a variable is a pointer to the anonymous function expression on the right side and can be reassigned, a function declaration declares a function name that is just that, and not a variable name).

      //Setup a constructor function. MUST be used with "new f()", otherwise
      //"this" would be the global object ("window" in browser environments).
      var F = function () {
          this.variable = 42
      };

      //produce a new object, set this to point to it and call f()
      var a  = new F();

      So far there is no difference to just writing

      //don't actually do this, code just for comparison!
      //otherwise the next step would not work
      var a = {
          variable = 42
      }

      But now let's add a function to the prototype object of F().

      Background: 
      functions are objects, but objects aren't functions. Function objects in Javascript all have a member called prototype.  When you declare a new function prototype points to an empty object.

      //This ADDS a member to the existing prototype object.
      //One could also simply replace the whole prototype object
      //with ones own object.

      F.prototype.show = function () {
          return this.variable;
      }


      Now you can do this:

      a.show()
      (returns 42)

      What happened? When you create a new object using a constructor function rather than by assigning an object literal "{}", the newly created object gets a "secret link" - not to the constructor function but to its prototype! In Firefox's Javascript engine that link can be accessed using __proto__ (but don't ever use it in your programs or it won't run in other browsers - that linkage is "secret" and although part of the Javascript language, it is not officially exposed to the Javascript code you write).

      Let's do a check (only works in Firefox!):

      a.__proto__ === F.prototype
      returns "true" (by using === we assure that the objects are indeed identical, i.e. the two variables point to the same memory location)

      So what is my point? Well, if you create an object without a constructor, you don't get the secret link. Therefore it does not inherit anything from a parent object (the constructor function object). So in the original example below saying the two ways to create the object are the same is correct for all practical purposes of the particular example, I think it's a good idea to point out the hidden implementation difference that DOES exist - and is a core feature of the language and makes the YUI possible in the first place, since it makes heavy use of that inheritance mechanism.


      Michael


      PS: One other aspect - again for the previous poster, : For singleton objects it may not matter, but if you create a constructor function methods should not be added to the created object inside that constructor using "this.memberFunction". Instead, add them to the constructor functions prototype. In the below example with the inline anonymous constructor that wouldn't be possible of course, I can't think of a way to add to an anonymous function's prototype member... well, except for maybe something like this: var a =(function(){...}).prototype = {foo:function(){...}}
      :-)


      --- "Caridy Patino" <caridy@...> wrote:
      > > YAHOO.au.com.company.SomeWidget = new function(){
      > >      this.rootLayout=null;
      > >      this.renderLayout=function(){
      > >              YAHOO.au.com.company.SomeWidget.rootLayout= new
      > > YAHOO.widget.Layout({  });
      > >              .....
      > >      }
      > > }
      > > -------------------------------------------------------------------
      > > YAHOO.au.com.company.SomeWidget = {
      > >         renderLayout: function(){
      > >
      > >         }
      > > }
      > Both definitions are the same... you are creating a new object, and
      > setting some properties/methods to that object. The second sintax is
      > more likely, and widely used.
      >
      > And the other approach is the prototype approach, but you can get more
      > ACADEMIC definitions from the Douglas trilogy in the YUI theater:
      >
      > http://developer.yahoo.com/yui/theater/
    • Show all 25 messages in this topic