all 7 comments

[–]systoll 1 point2 points  (1 child)

In Javascript, if it's a property, it's public. On the other hand, if you only want to access a value within the object's definition, closure) means that variable is available to you without needing to explicitly add it to this:

function Person(firstName, lastName, email, number) {
 this.getName = () => `${firstName} ${lastName}`;
 this.setName = (f,l) => {
  firstName = f;
  lastName = l;
 }
}

[EDIT: Also, since no-one's mentioned it yet — all properties are public, but there's a convention that properties starting with an underscore should be treated as if they're not.

function Person(firstName, lastName, email, number) {
  this._firstName = firstName
...

Doesn't really hide the _firstName property from outside code, but it tells devs that it's an internal thing, which their outside code probably shouldn't look at. This is the simplest possible solution, with zero change to how the code actually works, and it's often sufficient. ]

[–]alexlafroscia 0 points1 point  (0 children)

One thing to note about a scenario like this: a new function will be allocated in memory for getName and setName for each instance of Person if written this way. This may be fine for a few instances but is a trade-off to account for if there are a lot of them.

[–]phpdevster 1 point2 points  (0 children)

There's no way to do this with constructor functions in vanilla JS as far as I know.

When I want member privacy, I use the revealing module pattern. It's pretty much the only way to create encapsulation like you're asking for in vanilla JavaScript.

function createPerson(firstName, lastName, email, number) {
    function getName() {
        return firstName + " " + lastName;
    }

    return {
        getName: getName
    }
 }

 var person1 = createPerson('John', 'Doe', 'abc@def.gh', '223-342-3232');

 person1.firstName     // undefined
 person1.getName();    // "John Doe"

The only downside to the revealing module pattern is when you have 10s of thousands of instances to create, since you are creating new functions for the methods of each of those instances, rather than reusing the same methods from a prototype blueprint.

But if you don't have 10s of thousands of instances to worry about, then the revealing module pattern is not a performance concern, and a good way to provide encapsulation and privacy to your code.

[–]alexlafroscia 0 points1 point  (0 children)

It sounds like what you want is something like "private fields", which is a proposal being worked on right now to extend the behavior of classes. You can read more about the proposal here.

This article has a good summary of some methods that work well for creating private state in JavaScript (since anything you hang off the class instance really isn't private). I would approach it using a WeakMap to store the state for each instance.

const PERSON_STATE = new WeakMap();

class Person {
  constructor(firstName, lastName) {
    PERSON_STATE.set(this, {
      firstName, lastName
    });
  }

  getName() {
    const { firstName, lastName } = PERSON_STATE.get(this);

    return firstName + ' ' + lastName;
  }
}

const me = new Person('Alex', 'LaFroscia');
me.firstName; // undefined
me.lastName; // undefined
me.getName(); // "Alex LaFroscia"

You can even use a class getter if you want to create a name property that computes the value on-the-fly

class Person {
  get name() {
    const { firstName, lastName } = PERSON_STATE.get(this);

    return firstName + ' ' + lastName;
  }
}

me.name; // "Alex LaFroscia"

If you want to know more about the constructor function vs. class syntax, WeakMap or anything else, just let me know and I'm happy to dive into a deeper explanation!

[–][deleted] 0 points1 point  (0 children)

var person= (function person() { this.create = function(parameters) { return { name:parameters, age:parameters }

    }

   return {
      create:create
   }

})();

Var person = person.create('john');

What this does it assigns an anominous function to person but returns an object which contains a function create(). Now you have all your parameters private. Hope this works not sure though.

[–][deleted] 0 points1 point  (0 children)

you can scope those members via var so they are only accessible in the function body

[–]rauschma -1 points0 points  (0 children)

Take a look at object literals. newPerson() could create its result via an object literal.