Hi Nathan

On Feb 28, 12:12 am, Nathan Sweet <[email protected]> wrote:
>  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:

Good question,

The only ways to create a Function instance (I believe) are (a) a
function declaration, (b) a function expression, or (c) new
Function.

In each case the prototype chain for a function will be:

[function instance]
|
|
Function.prototype  [of which "overloadSetter" is a property]
|
|
Object.prototype
|
|
null  (per Rob G)

In order for "this" in "overloadSetter" to point to the the "function
instance" (as it must in order to work), "overloadSetter" must either
appear on "Function.prototype" or "Object.prototype" or as a direct
property of the function instance.

By "at least" I actually meant that "Object.prototype" or direct
property were  alternatives. In reality you would not add to
Object.prototype, as Object.prototype is inherited by everything, not
just functions. Also you would not add "overloadSetter" directly to
your function instance, because that means that it is not available to
other functions:-

Example of a direct property!

function myinstance()
{

}

myinstance.overloadSetter = function () {....};
var wrapped = myinstance.overloadSetter();


>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;
>      };
> }

In your example of "someObject.prototype" you are correct that this
would not work, for two reasons:-

(a)     "someObject.prototype" itself may be misleading you.   If you
want to create your own inheritance chain then you would do:-

function MyConstructor()
{

}
MyConstructor.prototype.someProperty = 1;
MyConstructor.prototype.someMethod = function (){};

But in that case, these are private prototype chains for objects
created with new MyConstructor.

Any other objects in JavaScript (including functions) would not
inherit any of these properties or methods, as they would not appear
in their prototype chains.

> 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.

Fair points.  I'll try to be a bit clearer.

You dont have to call it immediately at declaration.

You could do:-

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;
        };
};

var myFunc = function(a, b) { alert (a + b); };

var myOverloaded = myFunc.overloadSetter();   // equivalent to
function(a, b) { alert (a + b); }.overloadSetter();

assert(myFunc !== myOverloaded);

The expression "myFunc.overloadSetter()" does the following:-

1.   Looks for overloadSetter on myFunc - FAIL
2.   Looks for overloadSetter on Function.prototype - FOUND
3..  In overloadSetter "this" = myFunc, and "self = this"
4.   In overloadSetter return a new anonymous function "return
function(a,b)" (which has the variable "self" in its scope chain which
points to myFunc
5.   Assign the anonymous function returned by overloadSetter to
myOverloaded (this is the bit you could be missing, as it is not
obvious)
6.   myOverloaded then refers to the the following function, where
"self" points to myFunc:-

  function(a, b){
                if (a == null) return this ;
                if (usePlural || typeof a != 'string'){
                        for (var k in a) self /*myFunc*/.call(this, k,
a[k]);
                } else {
                        self /*myFunc*/.call(this, a, b);
                }
                return this;
        };

There is no implicit passing of arguments.  When I call
myOverloaded(1,2), there is an express passing of "1" and "2" to
myFunc with "self.call(this, 1, 2)"

Hope this helps further.

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]

Reply via email to