Element.Layout class: How is the _object instance property created?

25 views
Skip to first unread message

petrob

unread,
Sep 1, 2012, 11:30:19 AM9/1/12
to prototype-s...@googlegroups.com

First of all, I think I fully understand the implications of using Class.create to generate classes in Prototype together with how wrapping works and the use of the $super argument in methods that want to call the similarly -named method on the parent class's prototype.
Also, it's clear that the constructor of any class (in Prototype) just delegates the task of creating instance methods to the initialize prototype method by passing on any arguments it is getting at instantiation time.
So, if a class wants to use the instance- member- making capability of the parent class, the parent's initialize method is called through $super inside its initialize .

A very clear example of this is how Ajax.request uses Ajax.Base to make sure all the necessary arguments are set to a default, (and some are then normalized) if they are not taken in through the options hash.

 Ajax.Request = Class.create(Ajax.Base, {
  _complete: false,

  initialize: function($super, url, options) {
    $super(options);
    this.transport = Ajax.getTransport();
    this.request(url);
  },
... cut ...
});

This is how far things are clear for me.
------------------------------------------------------------------------------------------------------
Now, Element.Layout  inherits methods from Hash and in its initialize method  the parent Hash's initialize is called WITHOUT passing any arguments to it!

    initialize: function($super, element, preCompute) {
      $super();
      this.element = $(element);
     
......cut.....  
    }

At the same time, Hash.initialize is waiting for an object as an only argument to store it on the instance, isn’t it?

var Hash = Class.create(Enumerable, (function() {

  function initialize(object) {

    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);

  }

..cut..

});

My question is: How will the this._object ever be created on the Element.Layout instance?



petrob

unread,
Sep 7, 2012, 1:20:38 PM9/7/12
to prototype-s...@googlegroups.com
Finally, I got it!

In the inside of Hash.initialize Object.clone is called:


var Hash = Class.create(Enumerable, (function() {
  function initialize(object) {
    if(typeof object == 'undefined'){alert(arguments.callee)}

    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
  }
..cut..
}

 .. and it takes an empty object literal to extended it with all the properties of the source object:

  function clone(object) {
    return extend({ }, object);
  }

So, there is a returned "empty" object literal even if Hash.initialize is called without the expected "object" argument just like in Element.Layout.initialize.

This is NOT AT ALL an intuitive solution and can only  create much confusion about how Class creation works in Prototype. The transparent ( commonly used ) solution is to default the object argument to an empty object literal in the inside of Hash.initialize:

 function initialize(object) {
    if(Object.isUndefined(object)){ object = {};}

    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
  }
Thanx guys!
 



Reply all
Reply to author
Forward
0 new messages