Object composition challenge (was: Using Object Literals as Classes)

# David Bruant (14 years ago)

Challenge at the bottom

Le 16/03/2012 23:34, John J Barton a écrit :

On Fri, Mar 16, 2012 at 3:04 PM, David Bruant <bruant.d at gmail.com> wrote:

Unfortunately, methods on prototype require to have properties that are public.

If you avoid prototype methods, all your attributes and private methods can be shared by public method scopes. I think you are mixing up interface and implementation here, in a funky way ;-)

I was just talking about implementation.

The interface of the 'prototype', a pointer to a table for fallback lookup, allows implementation inheritance. But it does not demand it, it's just a choice you may make.

You can, for example, create an implementation hierarchy, then encapsulate it in a an interface hierarchy. The functions on the .prototype for the interface may be pointers to functions on the encapsulated implementation.

Something like:

var Foo = (function makeFoo(impl) { function Foo() { impl.call(this, ...); } Foo.prototype = { bar: impl.bar, baz: impl.baz }; return Foo; })(theImpl);

So prototype does not mean non-encapsulation.

I agree with you, but it's not what I meant.

I guess I should provide an example of the problem that is hard to solve in JavaScript (ECMAScript 3 and 5). Here is the challenge !

A Person knows one secret and has methods like .eat(), .walk()... There is no method in the Person interface to reveal the secret either directly or indirectly. A ComputerSavvyPerson is a Person, but has an additional .getMD5HashedSecret() method which returns the hashed secret. A StupidPerson is a person with a method .tellSecret()

I want to be able to create Persons, ComputerSavvyPersons, StupidPersons and the secret to be properly encapsulated (only revealed by stupid people through the dedicated method). I'd like to emphasis that the secret belongs to the person and none of the subclasses. I could add arbitrary subclasses and don't want to add a secret to each child subclass. Last constraint : I want each type to be in a different file (no shared private scope). This is important for code reuse. If I want to reuse the Person code, I don't necessarily want to reuse all its subclasses.

This is a piece of cake with Java's protected. It is much convoluted in JavaScript. I think this kind of problem being hard to solve in JavaScript is the reason why so many frameworks like Node.js make the choice to expose their internals.

# John J Barton (14 years ago)

On Fri, Mar 16, 2012 at 4:18 PM, David Bruant <bruant.d at gmail.com> wrote: ...

This is a piece of cake with Java's protected. It is much convoluted in JavaScript. I think this kind of problem being hard to solve in JavaScript is the reason why so many frameworks like Node.js make the choice to expose their internals.

I doubt this is the reason. Many JS devs recognize that private/protected are great for the 1% programmers who work on clearly defined, simple problems. Predicting what needs to be exposed and what does not in real problems is hard and fails. This extract a cost in real projects. The benefits of private/protected are exaggerated, as can be clearly demonstrated by admiring the success of languages without it.

I'm not saying private/protected is a bad thing, I'm only disputing your conclusion.

jjb

# Jonas Höglund (14 years ago)

On Sat, 17 Mar 2012 00:18:48 +0100, David Bruant <bruant.d at gmail.com>

wrote:

A Person knows one secret and has methods like .eat(), .walk()... There is no method in the Person interface to reveal the secret either directly or indirectly. A ComputerSavvyPerson is a Person, but has an additional .getMD5HashedSecret() method which returns the hashed secret. A StupidPerson is a person with a method .tellSecret()

For example, see gist.github.com/2053624. I don't see what's

wrong with using closures for hiding variables, when necessary.

[snip]

This is a piece of cake with Java's protected. It is much convoluted in JavaScript. I think this kind of problem being hard to solve in JavaScript is the reason why so many frameworks like Node.js make the choice to expose their internals.

I think "exposing the internals" is more "idiomatic" in JavaScript to expose the internals rather than trying to hide them, similarly to how I think it's idiomatic to assume the correct types of parameters rather than manually checking their types (in many cases at least, especially for internal functions). The "exposing all properties" flows well with how prototypal inheritance works, but even disregarding that we also see "exposed internals" in other dynamic languages than JavaScript, such as Python.

David

Jonas