On Wed, May 23, 2012 at 6:36 PM, alessioalex <[email protected]> wrote:
> That wouldn't work because you cannot call doubleFoo.m directly without
> creating a new doubleFoo objected.
Yeah, that was a typo.
> Secondly, even if you would instantiate a
> new doubleFoo object the m function will get overriden by foo.m (since
> that's stored in the prototype).
Well, that's because you made it so. Mine works differently, see below.
> Last but not least, you cannot call
> this.inherited if there's no class to inherit from (a class inherits from a
> super class if the uber property stores a reference to that super class).
>
> What you can do instead is extend the foo class with its own m method and
> then call inherited inside the m function:
>
> var Cls = require('Cls');
>
>
> var Foo = Cls({
> methods: {
> m: function (x) {
> console.log(x);
> }
> }
> });
>
> var DoubleFoo = Cls({
> uber: Foo,
> methods: {
> m: function(x) {
> // first argument is name of super function, second is array of
> arguments
> this.inherited('m', [x * 2]);
> }
> }
> });
>
> var df = new DoubleFoo();
> df.m(1);
Well, this is plain old class inheritance. The downside of this
approach you cannot import DoubleFoo's behavior to another class Baz
with a base class.
Whereas defineClass allows that:
// define a trait
var DoubleXInM = {
m: function (x) {
return this._super(x); // call a method that _will be_ inherited.
}
};
var DoubleFoo = defineClass({
_super: [Foo, DoubleXInM],
// other stuff
});
var BaseBaz = defineClass({
m: function (x) {
alert(x);
}
});
var Baz = defineClass({
_super: [BaseBaz, DoubleXInM]
});
new Baz().m(1); // alert(2)
This approach allows putting a behavior to a trait and reusing it in
_different_ class hierarchies.
It makes sense in big systems.
> You may be asking yourself why the heck do i ask for the name of the super
> function when calling inherited?
>
> Well, I could have just used this.inherited(arguments) or simply
> this.inherited() and make the function call super with the last function
> that was executed on the child, like Klass (https://github.com/ded/klass)
> does.
> The problem with that is that if I call functionA and functionB of the "sub
> class" (the class that inherits from the super class) and function a would
> call this.inherited() after 2 seconds for example that wouldn't work
> (because the last function called would be functionB not functionA).
>
> Example that wouldn't work:
>
>
> var Foo = Cls({
> methods: {
> m: function (x) {
> console.log(x);
> }
> }
> });
>
> var DoubleFoo = Cls({
> uber: Foo,
> methods: {
> m: function(x) {
> var that = this;
> setTimeout(function() {
> that.inherited();
> }, 2000);
> },
> bla: function() {
> // do stuff
> }
> }
> });
>
> var df = new DoubleFoo();
> df.m(1);
> df.bla();
>
> But with the approach from Cls (specifying inherited with name of super
> function and arguments) this does work properly (although more verbose).
Yes, I am aware of that problem and I have warning in me readme:
---
The _super field value changes from method call to method call, so it
may be used only in the method that has overridden the base method. Do
not use it in a nested function unless you know what you are doing.
----
But I like the approach I used more because:
1. It's shorter and works in the majority of cases
2. You don't have to change these string(s) when you rename a method
as a part of refactoring
In such cases I recommend saving the method to a variable:
{
m: function (x) {
var that = this,
super = this._super;
function a() {
return super.call(that, x);
};
}
a();
}
Thanks,
-Nodir
>
> On Wednesday, May 23, 2012 2:09:49 PM UTC+3, Nodir Turakulov wrote:
>>
>> On Wed, May 23, 2012 at 4:00 PM, Nodir Turakulov <[email protected]>
>> wrote:
>> > On Wed, May 23, 2012 at 2:17 PM, alessioalex <[email protected]>
>> > wrote:
>> >> I've made a OOP module myself a couple of days ago:
>> >> https://github.com/alessioalex/Cls
>> >>
>> >> It uses an extends function and a mixin function under the hood, very
>> >> basic
>> >> stuff.
>> >
>> > As far as I understand after a quick look at the readme, your mixins
>> > only overwrites properties without inheriting methods
>>
>> Sorry, the word "inheriting" is wrong here. I meant that a mixin
>> method cannot call a base method.
>>
>> -Nodir
>>
>> > Can I call a base/super method in a mixin method?
>> >
>> > var foo = Cls({
>> > methods: {
>> > m: function (x) {
>> > console.log(x);
>> > }
>> > }
>> > });
>> >
>> > var mixin = {
>> > m: function (x) {
>> > this.inherited(x * 1);
>> > }
>> > };
>> >
>> > var doubleFoo = Cls.mixin(foo, mixin);
>> > doubleFoo.m(1); // will it output 1 or 2?
>> >
>> > -Nodir
>> >
>> >> --
>> >> Job Board: http://jobs.nodejs.org/
>> >> Posting guidelines:
>> >> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
>> >> You received this message because you are subscribed to the Google
>> >> Groups "nodejs" group.
>> >> To post to this group, send email to [email protected]
>> >> To unsubscribe from this group, send email to
>> >> [email protected]
>> >> For more options, visit this group at
>> >> http://groups.google.com/group/nodejs?hl=en?hl=en
>
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to [email protected]
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en
--
Job Board: http://jobs.nodejs.org/
Posting guidelines:
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en