Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Encapsulation

Tags:

javascript

So I've been looking into full development object oriented JavaScript practices, and wonder about the following examples.

As I understand it, (and it makes sense to me) that the following 'secret' field is 'private' :

var MyObject = function() {

    var secret = 'sshhh';

    this.getSecret() = function() {
        return secret;
    }

}

and this is because the field secret has function scope that the inner function can access, but nothing outside ... so far so good.

But I've seen the following around (and especially in Douglas Crockford's book) :

var MyObject = function() {

    var secret = 'sshhh';

    return {
       getSecret : function() {
            return secret;
       }
    }   

}();

and was wondering what the difference is, why is it better? I understand that in this case we're not even returning the same object that the private field exists in, but don't see a huge benefit as you can't access the field directly either way.

like image 895
lucas1000001 Avatar asked Jul 27 '10 22:07

lucas1000001


3 Answers

Those examples are very different... The first creates a "MyObject" function that, when called as a constructor using new, will have a "getSecret" function as a property; the second creates a "MyObject" Object with a "getSecret" function as a property.

In that respect, this is sort of like the difference between a static method and a public method. In the first case, the method only exists when the constructor is called, not in the constructor itself. In the second case there is no constructor.

So let's say you have:

var MyObject1 = function() {
  var secret = 'sshhh';
  this.getSecret = function() {
    return secret;
  }
}

// ...

var MyObject2 = function() {
  var secret = 'sshhh';
  return {
    getSecret : function() {
      return secret;
    }
  }
}();

running some tests:

MyObject1.getSecret();
// TypeError: Object has no method 'getSecret'
var m1 = new MyObject1();
m1.getSecret();
// "sshhh"

MyObject2.getSecret();
// "sshhh"
var m2 = new MyObject2();
// TypeError: object is not a function

So MyObject1 is like a class, and MyObject2 is like a static class.

like image 82
Dagg Nabbit Avatar answered Oct 05 '22 19:10

Dagg Nabbit


In larger objects, having the returned object explicitly showing what is returned helps you see what is exposed in one place instead of worrying that you've missed a this.something.

like image 26
andrewmu Avatar answered Oct 05 '22 19:10

andrewmu


It's not any better - or worse. Its used in two different scenarios.

The first example you give would work well for using the function as a 'class':

 stuff = new MyObject();

The second example works well for defining an inline object with some functions on it / a "singleton".

like image 33
gnarf Avatar answered Oct 05 '22 21:10

gnarf