Julian,
Thanks for the reply. Let me add some clarifications/questions that I didn't
offer before.
1. I don't know quite what you mean in item 3 of your argument when you say:

>If you seek to access the method "overloadSetter" on a function,
>under point 1 above, the interpreter will eventually find it on the
>Function.prototype.  As a result, at the very least you need to set
>"overloadSetter" on the Function.prototype before you seek to access
>it on a given function instance, and if you want it to be accessible
>by all functions that you create.

 What do you mean by "at the very least"? What precedes this statement seems
to indicate that you think that the method could be implemented in the
prototype of any other object besides the prototype of 'Function' , and that
all other methods of said object could use said method, looking something
like this:
someObj.prototype.overloadSetter = function(usePlural){
       var self = this;
       return function(a, b){
               if (a == null) return this;
               if (usePlural || typeof a != 'string'){
                       for (var k in a) self.call(this, k, a[k]);
               } else {
                       self.call(this, a, b);
               }
               return this;
       };
}
 Now any method of someObj can access overloadSetter like so:
SomeObj.prototype.someMethod = function(a,b){
//does something with 2 arguments
}.overloadSetter();
Now any other method of SomeObj can invoke someMethod like this ( 'a' , 'b'
) or ( { a : b } ). This is incorrect and doesn't work, and (at least for
me) it is counter-intuitively incorrect and doesn't work.  I'm not sure if
you were agreeing with me here or not, but if you were implying that the
above code could work, I'm here to tell you that it doesn't.

2. Item 6 of your argument seems the most compelling, but I'm not sure what
you mean to imply. I understand that when var self = this, it's referring to
the primary function, but you say:

>Accordingly "overloadSetter" needs to
>be a direct property of a function or on the prototype chain for a
>function (i.e. Function.prototype, or Object.prototype), per item 4
>above.

Maybe I'm not understanding you, but that still doesn't explain, for me, why
'overloadSetter' must be invoked at the declaration of the function it is
acting upon. You say it has to "be a direct property of a function or on the
prototype chain", well that actually seems to be incorrect in this case. In
this case it seems that it has to be both the direct property of a function
and in the prototype chain, or maybe you could say that it has to be the
direct property of a function and said property is being accessed through
the prototype chain.

Here's a couple of questions that I think will offer better clarification to
my  initially vague query:
1. Is there an alternative way (maybe more verbose and inefficient, but
better for understanding) to represent what is going on when
'overloadSetter' is being invoked upon a function at said function's
declaration.
2. Why is the returned function in 'overloadSetter' being implicitly passed
the arguments of its primary function? They seem to come out of the clear
blue sky! It's almost as if the returned function in 'overloadSetter' is
semi-equivalent to the function it was invoked upon.

Thanks again,
Nate
On Sun, Feb 27, 2011 at 2:52 PM, Julian Turner <[email protected]> wrote:

>
>
> On Feb 27, 7:29 pm, nathanJsweet <[email protected]> wrote:
> > I've got a really interesting javascript pattern that I've been
> > scratching my head over for a while. I basically understand what is
> > going on with what I'm about to talk about, but I would like a fuller
> > explanation than what I've been able to find on my own. Method
> > invocation at declaration:
> >         I was wandering around the MooTools source code to figrure out
> what I
> > could learn and I ran into an interesting method attached to the
> > global 'Function' that basically allows for all new functions to have
> > a method that allows them to take their arguments regular-style
> > "function( a , b ){}" or as an object "function( { a , b } ){}". The
> > code goes as follows (I've eliminated some of the other things that it
> > does, such as circumventing a problem in IE where if a property with
> > the DontEnum attribute exists in the prototype chain, or if the
> > instance property is marked DontEnum, it is not enumerated, such as
> > 'hasOwnProperty'):
> >
> > Function.prototype.overloadSetter = function(usePlural){
> >         var self = this;
> >         return function(a, b){
> >                 if (a == null) return this;
> >                 if (usePlural || typeof a != 'string'){
> >                         for (var k in a) self.call(this, k, a[k]);
> >                 } else {
> >                         self.call(this, a, b);
> >                 }
> >                 return this;
> >         };
> >
> > };
> >
> > This isn't the interesting thing yet. What is interesting about this
> > function is how it is invoked. It absolutely has to be invoked at
> > declaration, it will not work if it isn't invoked at its invoker's
> > invocation. Here is a function that uses it that sets an string and
> > some other object as an extension:
> >
> > Function.prototype.extend = function(key, value){
> >         this[key] = value;
> >
> > }.overloadSetter();
> >
> > So we could use this to basically do something like this:
> >
> > someFunc.extend( 'someMethod' ,  function(){does something} ); OR
> > someFunc.extend( { 'someMethod' : function(){does something} } );
> >
> > My question doesn't revolve so much around 'how does this work', but
> > as to 'why does this work', so if you're 100% sure of EXACTLY why this
> > is working than please tell me. Before you do consider that this
> > pattern can only be used on the global 'Function' object (seriously
> > try it), it cannot be used in some other parent object basically you
> > couldn't replace the word 'Function' in the above code with anything
> > else, this ONLY works with the global 'Function' object, but why? I
> > guess that's my question. I understand all of the above code and how
> > it's working, but I don't understand why it's working.
>
> Hi
>
> I'll have a go.
>
> 1.   Inheritance in JavaScript is implemented through chains of
> prototype objects, ending ultimately at Object.prototype.  If you
> access a property (including a property referencing a function - i.e.
> a method) on an object, and the object does not have that property as
> its own, then the interpreter will see if the the object's prototype
> has that property, and if not whether that prototype's own prototype
> has that property, and so on until it runs out at Object.prototype.
>
> 2.    Functions in JavaScript are first class objects like everything
> else (but what makes them special is that they are also callable).
> All functions are given the Function.prototype object in their
> prototype chain by the interpreter (as well  as Object.prototype).
>
> 3.   If you seek to access the method "overloadSetter" on a function,
> under point 1 above, the interpreter will eventually find it on the
> Function.prototype.  As a result, at the very least you need to set
> "overloadSetter" on the Function.prototype before you seek to access
> it on a given function instance, and if you want it to be accessible
> by all functions that you create.
>
> 4.    When you access a property (including one inherited in the
> prototype chain in 1 above) of an instance of an object (using DOT or
> [ ]) and that property is a method (i.e. a function reference), then
> the "this" property within that called method will be set by the
> interpreter to equal the specific object instance on which you used
> the DOT or [].  If that specific object was a function (see 2), then
> the "this" value will refer to the instance of the function object on
> which the method was called.
>
> 5.  In your above example, the "this" value in "overloadSetter" will
> point to the function created by the function expression appearing
> after "extend=" (your primary function), although of course it is
> never assigned to extend, as "overloadSetter()" returns another
> function to which it is a closure.  In "overloadSetter" the "this"
> value (your primary function) is then assigned to "self", so that it
> can be used as a closure in the nested function (a,b) returned by
> "overloadSetter".
>
> 6.  To finally answer your question, "overloadSetter" will only work
> if the "this" value is pointing to your primary function object,  in
> order for "self.call()" to work. Accordingly "overloadSetter" needs to
> be a direct property of a function or on the prototype chain for a
> function (i.e. Function.prototype, or Object.prototype), per item 4
> above.
>
> Regards
>
> Julian
>
>
>
>
>
>
>
>
> --
> To view archived discussions from the original JSMentors Mailman list:
> http://www.mail-archive.com/[email protected]/
>
> To search via a non-Google archive, visit here:
> http://www.mail-archive.com/[email protected]/
>
> To unsubscribe from this group, send email to
> [email protected]
>



-- 
Nathan Sweet
Web Developer
206.588.6137
nathansweet.me

-- 
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/[email protected]/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/[email protected]/

To unsubscribe from this group, send email to
[email protected]

Reply via email to