On 30/10/11 01:07, Axel Rauschmayer wrote:
Now, for the past few months, I've been defining my objects like this:

// where `clone' = Object.extend(Object.create(proto), props)
var Thing = function(){ return (
{ clone: _clone
, toString: toString
})

function clone(name){ return clone(Thing, { name: name }) }
function toString() { return '[thing ' + this.name + ']' }
}()

var Specific = function(){ return clone(Thing,
{ clone: _clone
, toString: toString
})

function clone(name){ return clone(Specific, { name: name }) }
function toString() { return '[specific ' + this.name + ']' }
}()

var foo = Thing.clone('foo')
var bar = Specific.clone('bar')
Where is _clone in the above code? You also could write the functions into the 
object literals then you wouldn’t need an IIFE.
Ah, those `clone' functions should be `_clone'. The underscore is just to avoid conflicts with the outer `clone' function.

Anyways, it is a matter of taste. I write function-heavy style, so I find it better to write something(other(x)) than this.something(this.other(x)). Defining the objects inside a closure allows me to define these little helper functions that would otherwise just clobber the prototype object if exposed — I usually expose them under a `internal' property though, so I can test them.

There's also the thing about my liking to have a list of all public properties of the object readily accessible in the code. With object literals it gets a bit more difficult, as the list of properties are lost in the definitions of such properties.

How about the following variation of your code? Would that still reflect your 
intentions or go against your taste? It’s very close to your next proposed 
solution.

     var Clonable = {
         clone: function() {
             var inst = Object.create(this);
             inst.init.apply(inst, arguments);
         },
         extend: function(props) {
             return  Object.extend(Object.create(this), props);
         },
     }

     var Thing = Clonable.extend({
         init: function (name) {
             this.name = name;
         },
         toString: function () {
             return '[thing ' + this.name + ']';
         },
     });

     var Specific = Thing.extend({
         // reuse Thing.init()
         toString: function () {
             return '[specific ' + this.name + ']';
         },
     });

     var foo = Thing.clone('foo')
     var bar = Specific.clone('bar')


/// Using an extended version of object literals
var Thing = {
constructor(name){ this.name = name }
,toString(){ return '[thing ' + this.name + ']' }
}

var Specific = Thing<| {
constructor(name){ this.name = name }
,toString(){ return '[specific ' + this.name + ']' }
}

var foo = new Thing('foo')
var bar = new Specific('foo')
That’s approximately how Irakli’s Selfish or my Prototypes as Classes work 
(both are ES5 libraries).
Yes, and to which I think class-syntax would be just a duplicated sugar — as long as you have the new <| and .{ operators, that is.

The one thing class-syntax would excel at, though, is the current semantics for 
super calls in ES.next. I find them particularly confusing, considering the 
relationship between functions and objects in JS. They make more sense with a 
static declarative syntax, but that might be just me.
Super-calls are the one thing that would stay the same between all current 
proposals!
Hm, wouldn't most features covered by the class-syntax be independent of syntax in the end? My point was that the nature of static |super| fits more naturally the static nature of the class-syntax than the dynamic nature of prototypes, even though object literals are declarative. People are likely to think about class-syntax in the same manner they reason about them in classical languages, I guess.
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to