7
\$\begingroup\$

Most of my coding experience is in C#. The way object oriented programming is laid out in C# is a bit different from NodeJS, hence this is my first NodeJS OOP for a Student class.

I'm trying to translate this C# structure of creating a class, object and methods to NodeJS:

class Student
    {    
        private int _age;

        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }

        private string _name;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private string _id;

        public string ID
        {
            get { return _id; }
            set { _id = value; }
        }
   }

Sample usage:

Student student = new Student();
student.Age = 12;
student.Name= "Tolani";
student.ID = "Pokemon1234";

NodeJS code:

// Constructor
   function Student(name, age, id)
    {
        // always initialize all instance properties
        this.name = name;
        this.age = age;
        this.id = id;
    }
    // Get the student Name
    Student.prototype.getStudentName = function()
    {
        return this.name;
    };

    // Gets the student Age
    Student.prototype.getStudentAge = function()
    {
        return this.age;
    };

    // Gets the student's ID
    Student.prototype.getStudentId = function()
    {
        return this.id;
    };
    // export the class
    module.exports = Student;
    var student = new Student('Tolani', 23, 'ddr1234');
    console.log('The student name is ' + student.getStudentName());

In general, can this be improved?

\$\endgroup\$
9
\$\begingroup\$

In modern versions of node.js (v6.0 or v4.x in strict mode) or when using an ES6 transpiler, you can use the ES6 class keyword:

class Student {
    constructor(name, age, id) {
        // always initialize all instance properties
        this.name = name;
        this.age = age;
        this.id = id;
    }
    getStudentName() {
        return this.name;
    }
    getStudentAge() {
        return this.age;
    }
    getStudentId() {
        return this.id;
    }
}

This creates the same underlying .prototype methods as your original code, but is obviously a bit cleaner syntax. Usage of the Student constructor and methods is identical.


Note: You don't need accessor methods for these properties. They are directly accessible as properties of the object.

If you don't want them directly accessible as properties (e.g. you only want methods to be able to access them), you can do this:

function Student(name, age, id) {
   this.getStudentName = function() {
       return name;
   }
   this.getStudentAge = function() {
       return age;
   }
   this.getStudentID = function() {
       return id;
   }
}

This "hides" the name, age and id instance variables in a constructor closure so they are only accessible to methods defined within the constructor. This does not use the prototype for methods and may (depending upon JS implementation) consume a bit more memory per object, but does give you property privacy.

\$\endgroup\$
  • \$\begingroup\$ "You don't need accessor methods for these properties." and you can't have them either in JS , at least not the way C# has them: you cannot have inherirable public methods that can access "private" properties. \$\endgroup\$ – I'll add comments tomorrow Jul 28 '16 at 23:33
  • \$\begingroup\$ @I'lladdcommentstomorrow - Actually, you can. I have an example in my answer. \$\endgroup\$ – jfriend00 Jul 29 '16 at 2:01
  • \$\begingroup\$ Sure, just not the way it is in C#. Each privileged function has to be created again per object. And reassignment is possible. \$\endgroup\$ – I'll add comments tomorrow Jul 29 '16 at 4:48
  • \$\begingroup\$ @I'lladdcommentstomorrow - Well, duhhh. Javascript isn't C#. They don't work the same and nobody should be trying to make them work the same. Learn Javascript for what it is and take advantage of what it does well and don't try to code in it like you code in C#. I did that when I first came to Javascript from C++ and it was a huge mistake. I wrote some butt ugly Javascript trying to make it work like C++. Big mistake. Because this was part of the conversation, I showed how you can have private instance variables in Javascript, not how to make things identical to C#. \$\endgroup\$ – jfriend00 Jul 29 '16 at 4:51
  • 1
    \$\begingroup\$ @dork - That's what my first example does, but if you want private instance variables like in the second example, you can't access those from prototyped methods so you have to assign the methods in the scope that you can access the private instance variables (in the constructor). \$\endgroup\$ – jfriend00 Feb 7 '17 at 10:05
4
\$\begingroup\$

In a Node.js enviroment using ES2015 (or at least with ES5) you could do like this:

const Student = (() => {
    let _Student = class {};
    let props = {
        Age: null,
        Name: null,
        ID: null
    };
    for (let prop in props) {
        Object.defineProperty(_Student, prop, {
            get: function() {
                return props[prop];
            },
            set: function(newValue) {
                props[prop] = newValue;
            },
            enumerable: true
        });
    }
    return _Student;
})();

let student = new Student();
student.Age = 12;
student.Name = "Tolani";
student.ID = "Pokemon1234";
console.log(student.Age, student.Name, student.ID); // 12 "Tolani" "Pokemon1234"

jsFiddle: https://jsfiddle.net/n3dgfqyq/

This would be the "translation" of your code. Maybe a bit verbose but it has the functionality where the properties works both as setter and getter.

Its not very common, since the class sintax is made to use separate setter and getter, and using this.prop as the value keeper and setting it or getting inside the method. That is the suggestion in jfriend00's answer.

\$\endgroup\$

protected by Jamal Oct 14 '18 at 8:00

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.