Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Classes

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:

  • Inheritance
  • Encapsulation (support for "private" properties/methods)
  • Instantiation (can have multiple instances of the "class", each with its own state)
like image 484
FtDRbwLXw6 Avatar asked Sep 26 '12 21:09

FtDRbwLXw6


People also ask

Are there classes in JavaScript?

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.

What are JavaScript classes?

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.

What is class in JavaScript with example?

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.

Should I use classes in JavaScript?

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.


2 Answers

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 :( 
like image 51
gion_13 Avatar answered Oct 13 '22 01:10

gion_13


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

like image 30
Joe Davis Avatar answered Oct 13 '22 02:10

Joe Davis