Classes should inherit from mixins
Reported by Kit Goncharov | June 28th, 2010 @ 01:19 PM
In Prototype and the current FuseJS API, mixins are statically
added (via Object.extend
) as class methods, instead of
inherited and added to the prototype chain. This introduces a
particularly nasty gotcha: classes that include a mixin
won't reflect any changes or updates to it:
var mixin = {
"myAwesomeMethod": function(){
console.log("Howdy!");
}
};
var Greeter = fuse.Class({
"greet": function(){
this.myAwesomeMethod();
}
}, mixin);
var greeter = new Greeter();
greeter.greet(); //=> "Howdy!"
mixin.myAwesomeMethod = function(){
console.log("Privet!");
};
//Class doesn't inherit the redefined method!
greeter.greet(); //=> "Howdy!"
Although we may not want to change this behavior due to backward-compatibility issues, I think it's rather unintuitive. It's also interesting to note that Prototype (which emulates a Ruby-like API for JavaScript) deviates from Ruby's behavior:
#Define our mixin (Ruby modules are roughly analogous to JS namespaces)
module Mixin
#Mixin method
def my_awesome_method
puts "Howdy!"
end
end
#Define our class
class Greeter
#Include the mixin with our awesome method
include Mixin
#Class/instance method
def greet
my_awesome_method
end
end
#Instantiate a `Greeter`
greeter = Greeter.new
greeter.greet # => "Howdy!"
module Mixin
#Redefine our mixin method
def my_awesome_method
puts "Privet!"
end
end
#Class inherits the redefined method
greeter.greet # => "Privet!"
What do you guys think? Should we update the class API so that all classes automatically inherit from mixins as well?
Comments and changes to this ticket
-
Kit Goncharov June 28th, 2010 @ 01:34 PM
A possible disadvantage of doing this is that we could easily end up with a long prototype chain, especially with multiple mixins and a superclass...
-
Radoslav Stankov June 29th, 2010 @ 03:57 AM
This could be useful (At least in Ruby is useful). The way ruby handles it is adding "something" like ghost classes which point to the mixin. In js we could use the same strategy.
I'm not sure if this could be done in performance wise ( I could be wrong ). I think I have seen something build whit inherit mixis here - http://jsclass.jcoglan.com, but for every mixin object is actually a class.
-
John-David Dalton September 2nd, 2010 @ 05:50 PM
I didn't think of
mixins
like that. In fact I made them so they couldn't be used in a way to work with inheritance, (I have checks that stop it). -
John-David Dalton September 2nd, 2010 @ 05:53 PM
FuseJS Class API
var SomeClass = fuse.Class(superclass, plugins, mixins, statics); SomeClass.addMixins({ ... });
-
John-David Dalton September 2nd, 2010 @ 05:57 PM
Making them update when changed would require some kind of wrapper around the source method that then checks the real method:
//... 'someMethod': function() { return mixin.someMethod.apply(mixin, arguments); } //...
-
John-David Dalton September 12th, 2010 @ 01:12 AM
- Milestone cleared.
- Tag set to enhancement
-
Kit Goncharov February 28th, 2011 @ 10:15 PM
- State changed from new to invalid
- Milestone order changed from 5 to 0
The general consensus seems to be in favor of keeping the existing Class API due to performance concerns and compatibility with the Prototype API. Closing as
invalid
.
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป
JavaScript frameworks share similar features and functionality such as DOM manipulation, event registration, and CSS selector engines. FuseJS attempts to incorporate the strengths of these frameworks into one stable, efficient, and optimized core JavaScript framework.