Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the modern way to structure a "class" in JavaScript? [closed]

Tags:

How to build a "class" (with properties and methods) upon which will be created a lot of instances?

like image 253
Frank Furd Avatar asked Feb 05 '10 07:02

Frank Furd


People also ask

How do you structure a class in JavaScript?

JavaScript does not use classes in the same way as Java, C++ or the like. One way to achieve your effect is to define a function in which the this keyword is used--accessing members roughly as you would in Java. Then, use the new keyword in calling this function to create an object.

Are JavaScript classes closures?

Closures and classes behave differently in JavaScript with a fundamental difference: closures support encapsulation, while JavaScript classes don't support encapsulation. NB: There is a proposal for this and it is in stage 3. It's enabled in some browsers by default and can also be enabled through a Babel plugin.

Are classes introduced in modern JavaScript?

JavaScript, being a prototype-based language, has something called constructor functions. Classes, introduced with ES6 provide “syntactical sugar”, that is comparable to inheritance in object-oriented languages. Classes are special functions meant to mimic the class keyword from these other languages.

What is enclosing class in JavaScript?

The "Private field must be declared in an enclosing class" error occurs when we try to read a private value directly from our code outside of the class object. To solve the error, make sure to only read private values from inside of the class. Here's an example of how the error occurs. index.js. Copied!


2 Answers

The modern way is to use class, as introduced in ES6.

class Movie {      constructor(name) {          this.name = name;          // The "_" prefix is commonly used to denote "private" members.          this._id = +new Date();      }        getName() {          return `${this.name} ${this._id}`;      }        setName(name) {          this.name = name;      }  }    const movie = new Movie('Beerfest');    console.log(movie.getName());

The above example provides an equivalent interface to the original examples from 2010.


Original answer from 2010:

In "modern" JavaScript, there are three popular methods for defining objects.

The first method is the classic method and is still popular because of its simplicity; however, it is discouraged by MDC in favor of the second method because of the inefficiency of having to redefine each function every time an instance of the object is created.

// Constructor, methods and members all rolled up into one definition var Movie = function(name) {     this.name = name;     // Note that private members can be created using the closure property     var _id = +(new Date());      this.getName = function() {         return this.name + " " + _id;     };      this.setName = function(name) {         this.name = name;     }; };  var m = new Movie("Beerfest"); 

The second method is a variation of and can be used interchangeably with the first. It is also useful for adding new methods to existing objects via the prototype property. Private members and methods are not possible in this form.

// Constructor is separate from its methods var Movie = function(name) {     this.name = name; }  Movie.prototype.getName = function() {     return name; };  Movie.prototype.setName = function(name) {     this.name = name; };  var m = new Movie("Kill Bill"); 

The third method is to use the module pattern, which makes it possible to instantiate objects without having to use the new operator.

var Movie = function (name) {     var _id = +(new Date());     var privateMethod = function() { alert(_id); };      // All methods and members defined here are public     return {         name: name,         getName: function() {             return this.name + " " + _id;         },         setName: function(name) {             this.name = name;         }     }; };  var m = Movie("Stackoverflow: the movie"); 

Note that in the first and third methods, you can use private access members and methods. But be aware that to use this within private methods some must happen.

like image 192
Justin Johnson Avatar answered Nov 23 '22 02:11

Justin Johnson


// I like this pattern..  // class function Person(name, birthdate) {   this._name = name;   this._birthdate = birthdate;   /* should not do this   * this.getAge = function() {   * }   * as the method will be constructed   * for each instance, better to let it   * be inherited from prototype, see below   */ }  // class methods Person.prototype.getBirthdate = function() {   return this._birthdate; }  // same as above, function as a method Person.prototype.getAge = function() {   var currentDate = new Date();   // age in millis   return currentDate - this._birthdate; }  // the get age method can be a "static" // method on the constructor function if you pass the // person object Person.getAge = function(person) {   var currentDate = new Date();   // age in millis   //no reference to this   return currentDate - person.getBirthdate(); }  // you could use it like this  myPerson = new Person("Steve", new Date("1980-01-01")); // returns age in millis myPerson.getAge(); // returns age in millis Person.getAge(myPerson); 

You could also use a anonymous function to simulate private and public

var PersonFactory = (function() {   // private area, no one can alter   // the person cache   var _cache = {}    // public area   return {     // returns a person born now     getPerson: function(name) {       if(_cache[name]) {         return _cache[name];       }       else {         _cache[name] = new Person(name, new Date());         return _cache[name];       }     }   } })();  var p = PersonFactory.getPerson("Leif"); p.getAge(); p = PersonFactory.getPerson("Leif"); // should be the same age / obj p.getAge(); 

I don't like this pattern though. The underscore warning _myVariable should be enough to keep users of your lib from using those variables / methods. I used it allot when I first discovered it because of my Java background.. It makes it difficult to work with prototype inheritance and can cause memory leaks.

like image 30
oyvindn Avatar answered Nov 23 '22 02:11

oyvindn