On Feb 28, 10:32 am, Nathan Sweet <[email protected]> wrote:
> Rob,
> I'm obviously not being clear enough.
> >There is no declaration, only assignment. And it can be done anytime
> >before the function is called, you can declare the function then
> >assign the modified version later if you want.
>
> Why does the method have to be assigned,
There are only two ways to assign values to properties: assignment and
function declaration. Noting that included in the mechanics of a
function declaration is assignment of a value to a property created on
the relevant activation object, so really there is only one way:
assignment.
> why can't it be called along with
> its primary function?
I don't understand what you mean by that, perhaps it doesn't matter.
> Why is the returned function in 'overloadSetter' being
> implicitly given the arguments from the function that 'self' is assigned
> (i.e. the function which adds overloadSetter as a property).
overloadSetter is a function that returns another function. The outer
function creates a reference to the function that it is called as a
property of (its this value)[1], then returns the inner function which
keeps a closure to that original function. The inner function is what
is actually called later, it does the logic of looking at the
arguments and calls the original function (the one kept as 'self') in
different ways depending on the types of arguments.
> Moreover, why
> doesn't the following code work:
> someFunction.extend({a:b}).overloadSetter(); (obviously if overloadSetter
Presuming you've assigned extend and overloadSetter to
Function.prototype, then it does 'work'.
Incidentally, since you don't keep the returned result, the call to
overloadSetter() is redundant.
> hasn't been directly assigned as a property to extend)
If it had, what difference would it make? overloadSetter is being
called as a property of the object *returned* by calling extend, it
isn't called on extend itself. And even if it was, it's on extend's
prototype chain so it will "work":
someFunction.extend.overloadSetter();
But that's somewhat useless as the returned value is ignored.
> Why isn't overloadSetter being found in the prototype chain in the above
> code.
It is. Consider:
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;
};
};
Function.prototype.extend = (function(key, value){
this[key] = value;
}).overloadSetter();
// Declare someFunc
function someFunc(){}
// Extend someFunc both ways
someFunc.extend( 'someMethod' , function(){alert('someMethod')});
someFunc.extend( { 'someMethod2' : function(){alert('someMethod2')}});
// Call methods
someFunc.someMethod(); // Shows 'someMethod'
someFunc.someMethod2(); // Shows 'someMethod2'
// Does this work?
var b = someFunc.extend({a:function(){alert('a');}});
// Hey, it does!
someFunc.a(); // Shows 'a'
// b is what extend returns, which is just someFunc
alert(b);
// Does this work?
b = someFunc.extend({a:function(){alert('a');}}).overloadSetter();
// Yes, b is someFunc wrapped just like extend was
alert('b.toString:\n' + b.toString() +
'\n\nb.extend.toString:\n' + b.extend.toString());
As I said earlier, you need to learn how prototype inheritance works
in ECMAScript. I don't know a good reference for that, I'm sure
someone else here will have one.
Once you have that down, learning identifier resolution will help too.
The best article you'll find on that is one written by Richard
Cornford:
<URL: http://www.jibbering.com/faq/notes/closures/ >
If you have any issues, ask here or in comp.lang.javascript.
1. Noting that a function's this keyword can be set to other values by
the call, but I'll ignore that here.
--
Rob
--
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]