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