Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #30232
| From | Scott Sauyet <scott@sauyet.com> |
|---|---|
| Newsgroups | comp.lang.javascript |
| Subject | Re: Comparing some of the ways to create objects |
| Date | 2016-04-06 23:42 +0000 |
| Organization | A noiseless patient Spider |
| Message-ID | <ne46s8$8td$1@dont-email.me> (permalink) |
| References | <hbc2gbpvk5nk24b0qupps6cjqn8fm3ar5e@4ax.com> <ndspod$lhh$1@dont-email.me> <0ebagb5j5s77hr64fhi3vlpr64asu3gous@4ax.com> |
John Harris wrote:
> Scott Sauyet wrote:
>
> <snip>
>> My techniques follow. I'm wondering if you see these ones as somehow
>> lesser techniques than the three you present. And if so, why is that?
>
> In general, any technique for the creation of one object can be wrapped
> in a function and used in several places and reused in other projects.
> The question is : does the function provided something extra that
> constructors can't provide *and* is this needed here? If not then an
> ordinary constructor is likely to be simpler and easier to read, and
> sometimes faster.
Of course, but in Javascript, there are a large number of such techniques,
and they each offer different advantages and disadvantages. As you noted,
#4 and #5 below each offer private properties. They also offer read-only
properties (not getters, BTW.) In addition, #5 can be used directly
anywhere a plain function is required without the overhead of adding
`new`, for instance as a callback to `Array.prototype.map`. #6 builds
the same sort of object prototype structure as your examples with
significantly less cognitive overhead.
I'm not trying to suggest that any of these are the definitive way to
handle OOP in Javascript. I don't think there is such a thing. But
these do offer useful features that differ from the features provided by
the techniques you provided. There are still others we could discuss.
That's what I was trying to get at. Do you think that there is something
special about your original list, or was it simply the first techniques
that came to mind?
>>=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>>
>> function Thing4(phrase) {
>> var count = 0;
>> this.toString = function() {return phrase;}
>> this.incr = function() {count++;} Object.defineProperties(this,
>> {text: {
>> get: function() {return phrase;}
>> }, count: {
>> get: function() {return count;}
>> }})
>> } // Thing4
>>
>> var a4 = new Thing4("Hello from Thing4 a4");
>> [ ... ]
>
> This makes count and phrase private variables and defines getters for
> them. I'm not a fan of private variables, getters, and setters unless
> they are really really needed. If your programmers include someone who
> can't stop corrupting objects while the program is running then get rid
> of them. On the other hand, in a library if someone corrupts your object
> then it's your fault : the customer is always right, i.e shouts louder
> :-(
Are you suggesting that your distaste for these constructs should dictate
how others write their code? If you release version 1 of your API and
some consumer of it starts to depend on what you thought was your
internals, you might start to enjoy to power of encapsulation when you
try to write version 2 and find that you can't modify those things you
always planned to clean up. If nothing else, encapsulation is generally
seen as one of the main tenets of OOP.
By the way, this does not define getter-functions. It only makes the
properties `text` and `count` read-only. I tried to write each version
in a way that might change the construction mechanism but otherwise kept
the public API of your original examples. That included the behavior of
the `incr` and `toString` methods and the existence of a readable `count`
property. (Looking back, I realize that the `text` property was not
necessary here.) Beyond that, I felt free to do as I chose, and here, I
chose not to allow a consumer to modify `count`. It seems likely that
the existence of a method like `incr` implies some invariant that would
be broken by a publicly mutable `count` property.
>> function thing5(phrase) {
>> var count = 0;
>> return {
>> toString: function() {return phrase;},
>> incr: function() {count++},
>> get count() {return count;}
>> };
>> } // thing5
>>
>> var a5 = thing5("Hello from thing5 a5");
>> [ ... ]
But, while this might not be suitable for millions of instances due to
the increased memory footprint, it also has the advantage of being easier
to use in higher-order abstractions:
["Phrase 1", "Phrase 2", "Prase 3"].map(thing5);
This is significantly more ergonomic than
["Phrase 1", "Phrase 2", "Prase 3"].map(function(phrase) {
return new Thing1(phrase);
});
And of course it shares the advantages of Thing4 in terms of greater
encapsulation.
>> var Thing6 = {
>> init: function(phrase) {
>> this.text = phrase;
>> this.count = 0;
>> },
>> incr: function() {
>> this.count++;
>> },
>> toString: function() {
>> return this.text ;
>> }
>> }; // Thing6
>>
>> var a6 = Object.create(Thing6);
>> a6.init("Hello from Thing6 a6");
>> [ ... ]
>
> I C++ circles, i.e in comp.lang.c++.moderated, an initialise function
> provokes cries of Eugh! It's annoying to have to write two things. More
> important, it's too easy to forget the init or to miss it out when
> copying and pasting elsewhere.
>
> Really, all this example does is to implement a constructor function.
> Why bother? [ ... ]
The C++ world has a clear-cut way to do this. In some ways C++ is to
Javascript like Python is to Perl. In Javascript, there simply is no
clear-cut definitive way to do these things, so we get to frequently
discuss varying approaches.
One advantage of this is well described in an article by Kyle Simpson
[1]. The point is that all Javascript's inheritance mechanism is meant
to do is to set up a delegation mechanism between simple objects. The
constructor function grafts an unfortunately messy layers onto this for
little benefit, and changes a very simple conceptual model [2] into an
extremely convoluted one [3].
I agree with Kyle Simpson in many ways. I think he (and Eric Elliott,
who is the loudest proponent of this point of view) oversell the style of
Thing6 as the only reasonable way to do OOP in Javascript. But it is
certainly *one* reasonable way.
Still, my big question is whether you find these techniques somehow
inferior to your original list. Do you believe your list captures the
essence of the set of reasonable object creation techniques in Javascript?
[1]: <https://davidwalsh.name/javascript-objects-deconstruction>
[2]: <https://davidwalsh.name/demo/JavaScriptObjects--OnlyObjects.png>
[3]: <https://davidwalsh.name/demo/JavaScriptObjects--Full.png>
-- Scott
Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-03 16:09 +0100
Re: Comparing some of the ways to create objects Scott Sauyet <scott@sauyet.com> - 2016-04-04 04:15 +0000
Re: Comparing some of the ways to create objects Stefan Weiss <krewecherl@gmail.com> - 2016-04-04 15:20 +0200
Re: Comparing some of the ways to create objects Scott Sauyet <scott@sauyet.com> - 2016-04-05 04:04 +0000
Re: Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-04 16:48 +0100
Re: Comparing some of the ways to create objects Scott Sauyet <scott@sauyet.com> - 2016-04-05 04:04 +0000
Re: Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-07 15:07 +0100
Re: Comparing some of the ways to create objects Scott Sauyet <scott@sauyet.com> - 2016-04-08 01:10 +0000
Re: Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-08 14:55 +0100
Re: Comparing some of the ways to create objects Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-04-04 22:12 +0200
Re: Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-05 09:57 +0100
Re: Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-06 16:41 +0100
Re: Comparing some of the ways to create objects Scott Sauyet <scott@sauyet.com> - 2016-04-06 23:42 +0000
Re: Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-07 16:09 +0100
Re: Comparing some of the ways to create objects Scott Sauyet <scott@sauyet.com> - 2016-04-08 02:05 +0000
Re: Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-08 15:43 +0100
Re: Comparing some of the ways to create objects Scott Sauyet <scott@sauyet.com> - 2016-04-09 00:01 +0000
Re: Comparing some of the ways to create objects Scott Sauyet <scott@sauyet.com> - 2016-04-09 16:46 +0000
Re: Comparing some of the ways to create objects Scott Sauyet <scott@sauyet.com> - 2016-04-10 16:51 +0000
Re: Comparing some of the ways to create objects Stanimir Stamenkov <s7an10@netscape.net> - 2016-05-08 17:27 +0300
Re: Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-10 11:31 +0100
Re: Comparing some of the ways to create objects John Harris <niam@jghnorth.org.uk.invalid> - 2016-04-10 11:52 +0100
csiph-web