Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #28100
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Newsgroups | comp.lang.javascript |
| Subject | Re: What technique I use in functions? |
| Date | 2015-06-15 23:31 +0200 |
| Organization | PointedEars Software (PES) |
| Message-ID | <2878487.iBXhT1CByJ@PointedEars.de> (permalink) |
| References | <0714ecc6-40b5-4500-b2f6-324bf75692b6@googlegroups.com> <objects-20150615015424@ram.dialup.fu-berlin.de> |
Stefan Ram wrote:
> Angel Rodriguez <cimadelmundo3000@gmail.com> writes:
>> I'm working on a project, and I am defining my style of
>> programming functions in javascript. With what I have
>> studied, I have seen three methods for working with functions
>> and I would like to know what kind of method you would use
>> considering scalability, performance, maintenance, etc.
>
> There are actually 28 ways to create objects in JavaScript.
In your dreams.
> […]
> I want to define a simple counter object that has
> a method that can count upwards by 1.
And unsurprisingly, in your infinite hubris you have managed to find and
suggest the least compatible, most error-prone, least efficient way to do
that.
> JavaScript is prototype-based, not constructor-based.
Those are not exclusive concepts. A constructor is a way to *initialize* an
instance independent of its prototype.
> So, we can always ignore constructors and just work
> with the prototypes!
>
> I create my global prototype:
>
> var counterPrototype = Object.create( Object.prototype );
… in an unnecessary complicated way, introducing an unnecessary dependency
on an implementation of ECMAScript Edition 5 and later. Any of
var counterPrototype = {};
var counterPrototype = new Object();
var counterPrototype = Object();
is equivalent to that; with increasing compatibility, but actually also
increasing error-proneness (the “Object” property can be overwritten).
> . I add my counter method »inc« to the prototype:
>
> Object.defineProperty
> ( counterPrototype, "inc",
> { value: function()
> { "use strict"; return this.v++; },
> configurable: true,
> enumerable: false,
> writable: true });
Which you could have done in the first step, and a readable manner
corresponding to anything that resembles recommended JavaScript code style,
of course:
var counterPrototype = Object.create(Object.prototype, {
inc: {
value: function () { "use strict"; return this.v++; },
configurable: true,
writable: true
}
});
whereas {enumerable: false} is the default, therefore can be omitted.
And even suppose it is supported, the "use strict" declaration serves *no*
purpose there. Backwards-compatible (because the string literal can be
ignored), but overkill.
> . I create new object from my prototype:
>
> var newCounter = Object.create( counterPrototype );
>
> . It still needs a field »v« with the counter value:
>
> Object.defineProperty
> ( newCounter, "v",
> { value: 0, configurable: true, enumerable: true, writable: true });
Again, incompatible overkill. The same can be achieved with
newCounter.v = 0;
as those property attribute values are the defaults for a simple assignment.
> . Done! I can now count:
>
> newCounter.inc();
>
> newCounter.inc();
>
> newCounter.inc();
You don’t say…
> . We have not used constructors, so »newCounter.constructor.name«
> is »Object«.
Which, almost needless for me to say, is _not_ a good idea. It is useful to
be able to tell apart types of objects. The Google V8 JavaScript console
and Chromium Dev Tools inspector use the prototype chain to get the type,
and the “constructor” property is an efficient way to do that in one’s own
code:
if (!(this instanceof this.constructor))
{
throw new Error("Method called on incompatible object");
}
It is also the most efficient, most refactoring-friendly way to clone an
object –
return new this.constructor(this);
– or to access "static", non-inherited properties shared among all instances
in prototype or instance methods:
this.constructor.foo
> If you often create objects in this manner, of course, you can
> put some parts of the above into a library, so that you then can
> create objects in this way even more easily.
More overkill.
> Advantages of this method: You have more control of the details.
> For example, instead of »Object.prototyp« above, I could have
> used »null«. Everything above would still work, but now
> »newCounter.constructor.name« would be undefined. And at some of
> the places above I could have used other values for »configurable«,
> »enumerable« or »writable«.
Object.create(null) is primarily useful for *data* objects as they would be
missing the .toString() and .valueOf() methods inherited from
Object.prototype by default.
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.
Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
What technique I use in functions? Angel Rodriguez <cimadelmundo3000@gmail.com> - 2015-06-14 14:38 -0700
Re: What technique I use in functions? Angel Rodriguez <cimadelmundo3000@gmail.com> - 2015-06-14 18:16 -0700
Re: What technique I use in functions? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-06-15 23:31 +0200
Re: What technique I use in functions? Angel Rodriguez <cimadelmundo3000@gmail.com> - 2015-06-15 17:54 -0700
Re: What technique I use in functions? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-06-16 08:49 +0200
Re: What technique I use in functions? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-06-15 23:31 +0200
Re: What technique I use in functions? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-06-16 00:08 +0200
csiph-web