I understand basic JavaScript pseudo-classes:
function Foo(bar) { this._bar = bar; } Foo.prototype.getBar = function() { return this._bar; }; var foo = new Foo('bar'); alert(foo.getBar()); // 'bar' alert(foo._bar); // 'bar'
I also understand the module pattern, which can emulate encapsulation:
var Foo = (function() { var _bar; return { getBar: function() { return _bar; }, setBar: function(bar) { _bar = bar; } }; })(); Foo.setBar('bar'); alert(Foo.getBar()); // 'bar' alert(Foo._bar); // undefined
But there are un-OOP-like properties to both of these patterns. The former does not provide encapsulation. The latter does not provide instantiation. Both patterns can be modified to support pseudo-inheritance.
What I'd like to know is if there is any pattern that allows:
JavaScript didn't originally have classes. Classes were added with the introduction of ECMASCRIPT 6 (es6), a new and improved version of JavaScript (ECMASCRIPT 5 being the older version). A typical JavaScript class is an object with a default constructor method.
Classes are a template for creating objects. They encapsulate data with code to work on that data. Classes in JS are built on prototypes but also have some syntax and semantics that are not shared with ES5 class-like semantics.
Note: JavaScript class is a special type of function. And the typeof operator returns function for a class. For example, class Person {} console.log(typeof Person); // function.
In JavaScript, you don't! You can write any program you want without utilizing classes or the this keyword ever! Indeed, the class syntax is somewhat new to JavaScript, and object oriented code was written with functions beforehand. The class syntax is just syntactic sugar over that function-based approach to OOP.
what about this :
var Foo = (function() { // "private" variables var _bar; // constructor function Foo() {}; // add the methods to the prototype so that all of the // Foo instances can access the private static Foo.prototype.getBar = function() { return _bar; }; Foo.prototype.setBar = function(bar) { _bar = bar; }; return Foo; })();
And now we have instantiation, encapsulation and inheritance.
But, there still is a problem. The private
variable is static
because it's shared across all instances of Foo
. Quick demo :
var a = new Foo(); var b = new Foo(); a.setBar('a'); b.setBar('b'); alert(a.getBar()); // alerts 'b' :(
A better approach might be using conventions for the private variables : any private variable should start with an underscore. This convention is well known and widely used, so when another programmer uses or alters your code and sees a variable starting with underscore, he'll know that it's private, for internal use only and he won't modify it.
Here's the rewrite using this convention :
var Foo = (function() { // constructor function Foo() { this._bar = "some value"; }; // add the methods to the prototype so that all of the // Foo instances can access the private static Foo.prototype.getBar = function() { return this._bar; }; Foo.prototype.setBar = function(bar) { this._bar = bar; }; return Foo; })();
Now we have instantiation, inheritance, but we've lost our encapsulation in favor of conventions :
var a = new Foo(); var b = new Foo(); a.setBar('a'); b.setBar('b'); alert(a.getBar()); // alerts 'a' :) alert(b.getBar()); // alerts 'b' :)
but the private vars are accessible :
delete a._bar; b._bar = null; alert(a.getBar()); // alerts undefined :( alert(b.getBar()); // alerts null :(
I think what you're looking for is the "Revealing Prototype Pattern".
Dan Wahlin has a great blog post: http://weblogs.asp.net/dwahlin/archive/2011/08/03/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-prototype-pattern.aspx
and even better Pluralsight course on this and other related JavaScript structures: http://pluralsight.com/training/courses/TableOfContents?courseName=structuring-javascript&highlight=dan-wahlin_structuring-javascript-module1!dan-wahlin_structuring-javascript-module2!dan-wahlin_structuring-javascript-module5!dan-wahlin_structuring-javascript-module4!dan-wahlin_structuring-javascript-module3#structuring-javascript-module1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With