[dojo-contributors] Stance on custom error types

Eugene Lazutkin eugene at lazutkin.com
Tue Jun 5 12:46:21 EDT 2012


It is uber-simple:

function makeClass(base, ctr, optMembers){
    var proto = base ? dojo.delegate(base.prototype) : {};
    if(optMembers){
        dojo.mixin(proto, optMembers);
    }
    ctr = ctr || new Function;
    ctr.prototype = proto;
    return ctr;
}

var B = makeClass(null, function(){}, {
    m1: function(){ console.log("m1"); }
});
var S = makeClass(B, function(){ console.log("S"); }, {
    m2: function(){ console.log("m2"); }
});
console.log("Here we go...");
var t = new S;
t.m1();
t.m2();

The function above supports single inheritance, optional constructors,
and optional class members, but doesn't support chaining (e.g., for
constructors), nor supercalls --- you can do them explicitly and
directly, if you know the inheritance chain. Adding supercalls is
trivial, yet will require to inline dojo.mixin() and add more steps for
copying members.

As you can see there is nothing to it. I was always fascinated when
people create OOP facilities without any support for class linearization
(or primitive class linearization) and manage to do it in hundreds lines
of incomprehensible code.

Cheers,

Eugene Lazutkin
http://lazutkin.com/




On 06/04/2012 10:12 PM, Bill Keese wrote:
> I agree, I'm just confused what Bryan was getting at with his comment
> "as long as we subclass correctly...".   But anyway, having custom error
> types sounds good to me.
> 
> PS: Are you saying that you can actually create the subclass with
> dojo.delegate()?   What's the syntax?   I can imagine with declare(),
> but not sure about delegate().
> 
> On Tue, Jun 5, 2012 at 11:39 AM, Eugene Lazutkin <eugene at lazutkin.com
> <mailto:eugene at lazutkin.com>> wrote:
> 
>     It is basically a hand-to-hand martial art to implement two simple
>     things:
> 
>     1) dojo.delegate() as was mentioned before.
>     2) A "universal" constructor that checks if it was invoked without
>     "new", and tries to fix this situation.
> 
>     If people are not afraid to type:
> 
>     throw new MyError();
> 
>     we can safely remove #2. And #1 will keep the rest to the minimum.
> 
>     I understand that some people want to "correct" JavaScript and make "new
>     Class()" and "Class()" to behave the same way --- JavaScript' standard
>     library does that too (including Error), yet the language keep both
>     concepts separate.
> 
>     The main objection is that if we call "Class()" without "new" it will
>     modify "this", which will be "window" ("global" on node.js) --- nobody
>     wants that. This is a valid problem but we lived with it for years and
>     other libraries did too. So I don't see it as a real-world problem.
> 
>     Obviously the strict mode eliminates the problem --- when calling a
>     function stand-alone and without "new" its "this" will be "undefined".
>     All modern browsers support it (and node.js too), while all old browsers
>     safely ignore it. I don't see any reasons not to use it to catch
>     possible problems with missing "new" and some other insane things.
> 
>     To sum it up: all hail the strict mode!
> 
>     Eugene Lazutkin
>     http://lazutkin.com/
> 
> 
> 
>     On 06/04/2012 04:11 PM, Tom Trenka wrote:
>     > No, it doesn't.  This example is a verbose version of someone
>     trying to
>     > use what is embodied in dojo.delegate (Boodman/Crockford
>     delegation) as
>     > a way of implementing a subclass.
>     >
>     > Mark's original example is the "traditional" way of doing it; Kris
>     > simplified that with Compose a little bit past that.
>     >
>     > Main point is whether or not we are creating custom error objects or
>     > not, and if so how do we remain consistent about it?
>     >
>     > -- Tom
>     >
>     > On Mon, Jun 4, 2012 at 3:45 PM, Bill Keese <bill at dojotoolkit.org
>     <mailto:bill at dojotoolkit.org>
>     > <mailto:bill at dojotoolkit.org <mailto:bill at dojotoolkit.org>>> wrote:
>     >
>     >     By "properly" you mean this chunk of code from that link?   It
>     seems
>     >     crazy to have 25 lines of code just to create an error subclass.
>     >     Does it really need to be that long?
>     >
>     >     var MyError = (function() {
>     >        function F(){}
>     >        function CustomError() {
>     >           // correct if not called with "new"
>     >           var _this = (this===window) ? new F() : this,
>     >               tmp = Error.prototype.constructor.apply(_this,arguments)
>     >           ;
>     >           for (var i in tmp) {
>     >              if (tmp.hasOwnProperty(i)) _this[i] = tmp[i];
>     >           }
>     >           return _this;
>     >        }
>     >        function SubClass(){}
>     >        SubClass.prototype = Error.prototype;
>     >        F.prototype = CustomError.prototype = new SubClass();
>     >        CustomError.prototype.constructor = CustomError;
>     >
>     >        // add a custom method
>     >        CustomError.prototype.CustomField1 = function(custom_1){
>     >           if (custom_1 != null) this.custom_1 = custom_1;
>     >           return this.custom_1;
>     >        }
>     >
>     >        return CustomError;
>     >     })();
>     >
>     >
>     >     On Tue, Jun 5, 2012 at 12:36 AM, Bryan Forbes
>     >     <bryan at reigndropsfall.net <mailto:bryan at reigndropsfall.net>
>     <mailto:bryan at reigndropsfall.net <mailto:bryan at reigndropsfall.net>>>
>     wrote:
>     >
>     >         As long as we're subclassing properly, I'd rather use custom
>     >         error types.
>     >
>     >         http://blog.getify.com/howto-custom-error-types-in-javascript/
>     >
>     >
>     >         Mark Wubben wrote:
>     >         > Dojo seems to do custom errors by adding a `dojoType`
>     property
>     >         to the error instance. Examples in `dojo/request` and
>     `dojo/io`.
>     >         The new Promise code however uses a subclassed Error.
>     >         >
>     >         > dojo/promise/CancelError:
>     >         >
>     >         >       function CancelError(message){
>     >         >               Error.captureStackTrace &&
>     >         Error.captureStackTrace(this, CancelError);
>     >         >               this.message = message || "The deferred was
>     >         cancelled.";
>     >         >               this.name <http://this.name>
>     <http://this.name> = "CancelError";
>     >         >       };
>     >         >       CancelError.prototype = new Error;
>     >         >       CancelError.prototype.constructor = CancelError;
>     >         >       return CancelError;
>     >         >
>     >         > I prefer subclassed errors because they're easier to
>     >         instantiate and test for (either using `instanceof` or
>     checking
>     >         their `name`). We could even add `dojoType` properties.
>     >         >
>     >         > What is your preference?
>     >         >
>     >         > In any case, we need to standardize these across the
>     codebase.
>     >         >
>     >         > --
>     >         > Mark Wubben
>     >         >
>     >         > http://novemberborn.net
>     >         > http://twitter.com/novemberborn
>     >         >
>     >         > _______________________________________________
>     >         > dojo-contributors mailing list
>     >         > dojo-contributors at mail.dojotoolkit.org
>     <mailto:dojo-contributors at mail.dojotoolkit.org>
>     >         <mailto:dojo-contributors at mail.dojotoolkit.org
>     <mailto:dojo-contributors at mail.dojotoolkit.org>>
>     >         >
>     http://mail.dojotoolkit.org/mailman/listinfo/dojo-contributors
>     >
>     >
>     >         --
>     >         Bryan Forbes
>     >         http://www.reigndropsfall.net
>     >
>     >         GPG Fingerprint
>     >         3D7D B728 713A BB7B B8B1  5B61 3888 17E0 70CA 0F3D
>     >
>     >
>     >         _______________________________________________
>     >         dojo-contributors mailing list
>     >         dojo-contributors at mail.dojotoolkit.org
>     <mailto:dojo-contributors at mail.dojotoolkit.org>
>     >         <mailto:dojo-contributors at mail.dojotoolkit.org
>     <mailto:dojo-contributors at mail.dojotoolkit.org>>
>     >         http://mail.dojotoolkit.org/mailman/listinfo/dojo-contributors
>     >
>     >
>     >
>     >     _______________________________________________
>     >     dojo-contributors mailing list
>     >     dojo-contributors at mail.dojotoolkit.org
>     <mailto:dojo-contributors at mail.dojotoolkit.org>
>     >     <mailto:dojo-contributors at mail.dojotoolkit.org
>     <mailto:dojo-contributors at mail.dojotoolkit.org>>
>     >     http://mail.dojotoolkit.org/mailman/listinfo/dojo-contributors
>     >
>     >
>     >
>     >
>     > _______________________________________________
>     > dojo-contributors mailing list
>     > dojo-contributors at mail.dojotoolkit.org
>     <mailto:dojo-contributors at mail.dojotoolkit.org>
>     > http://mail.dojotoolkit.org/mailman/listinfo/dojo-contributors
>     _______________________________________________
>     dojo-contributors mailing list
>     dojo-contributors at mail.dojotoolkit.org
>     <mailto:dojo-contributors at mail.dojotoolkit.org>
>     http://mail.dojotoolkit.org/mailman/listinfo/dojo-contributors
> 
> 
> 
> 
> _______________________________________________
> dojo-contributors mailing list
> dojo-contributors at mail.dojotoolkit.org
> http://mail.dojotoolkit.org/mailman/listinfo/dojo-contributors


More information about the dojo-contributors mailing list