I read the book "JavaScript : The Good Parts" book by Douglas Crockford and so many other resources and i'm a bit confused about implementing inheritance AND privacy in Javascript.
I'm coming from Java World, I've understood that I can simulate privacy via closure, or doing some inheritance via prototype but I want to do it in a javascript way.
I know I can perform some inheritance with the prototypal / parasitic pattern. This is good for performance but there is no way to use some privacy members properly (without creating some closure function each time a new object is instanciated)
I know I can inherit from object and use privacy members via the functionnal / parasitic pattern such as suggested by douglas Crockford but there is an obvious performance / memory issue since functions will be created again each time an object is instanciated.
Finally I'm wondering if good practices in other language such as privacy encapsulation make sense in JavaScript. I've seen some post here where people said "we don't care about privacy, just tell the world that this property should not be accessed from the outside and that's enough".
Should I consider that good practices in Javascript is reduced to prototypal / parasitic inheritance, with public interface and hope that developpers will use the library as expected ? Or maybe thinking in terms of inheritance and encapsulation is a "java" way to think and not a javascript one ? How to use the power of duck programming in javascript to achieve these goals ?
How to Safely Inherit Private Data in JavaScript
Often, people use underscores to denote that a property or method should be considered private. That's a bad idea.
Why Underscores Are a Bad Idea
Underscores do not guarantee data privacy, and there are a couple important problems that they create:
These are problems because encapsulation is an important feature of object-oriented design. Objects exist to solve a particular problem. Private methods may solve problems which are only related as an implementation detail. Implementation details are more likely to change than public interfaces, so code that relies on implementation details may break when implementation details change.
Exposing only your public interface hides implementation details which may change, which guides users to rely on supported features, rather than unsupported implementation details.
Use Functional Inheritance for True Data Privacy
Functional inheritance can be employed to inherit private data.
Functional inheritance is the process of inheriting features by applying an object augmenting function to an object instance. The function supplies a closure scope, which has the effect of hiding private data inside the function's closure.
Douglas Crockford coined the term in "JavaScript: The Good Parts". In Crockford's example, a child factory knows how to instantiate an object from an existing base factory, which has the effect of creating an inheritance hierarchy. However, that's a bad idea. We should always favor object composition over class inheritance.
You can create and compose functional mixins by modifying the pattern slightly to take the base object as a parameter.
The functional mixin enhances a supplied object instance. The function's closure scope may contain private methods and data. You may then expose privileged methods inside that function. It works like this:
Functional mixins can be composed together using standard function composition with any other base object and any other set of features. First, you'll need a compose function. You can use
compose()
from Lodash, Ramda, or any functional programming library that provides a standard compose function -- or just write your own:Now you can compose any number of mixins together using standard function composition:
For more versatile ways to compose factory functions using a variety of inheritance techniques, see the Stamp Specification.
References: