Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #28100

Re: What technique I use in functions?

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>

Show all headers | View raw


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


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