gremo
gremo

Reputation: 48909

Can I use a private method inside my prototype function in JavaScript?

I'm learning OO JavaScript, so this question may sound odd. Problem: normalize function should be private, that is not accessible/writable outside. Question: how can I access normalize from inside prepare prototype function?

var AuthHmac = AuthHmac || (function(_, CryptoJS) {
    function AuthHmac(options) {
        var options = options || {},
            normalize = function(s) { return s.toLowerCase(); };

        this.additionalHeaders = options.additionalHeaders || {};
    };

    AuthHmac.prototype.prepare = function(request) {
        request.headers = request.headers || {};

        _.each(this.additionalHeaders, function(value, name) {
            request.headers[this.normalize(name)] = value;
        });
    };

    return AuthHmac;

})(_, CryptoJS);

Upvotes: 1

Views: 261

Answers (4)

Guffa
Guffa

Reputation: 700422

Define the normalise function as a named function inside the scope, instead of putting it in a property of your object:

var AuthHmac = AuthHmac || (function(_, CryptoJS) {

  function normalize(s) {
    return s.toLowerCase();
  }

  function AuthHmac(options) {
    var options = options || {};

    this.additionalHeaders = options.additionalHeaders || {};
  };

  AuthHmac.prototype.prepare = function(request) {
    request.headers = request.headers || {};

    _.each(this.additionalHeaders, function(value, name) {
        request.headers[normalize(name)] = value;
    });
  };

  return AuthHmac;

})(_, CryptoJS);

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 816590

You can't. JavaScript does not have any concept of private or public properties and hence people use closures and scoping as "hack" to simulate privacy. But this comes at a cost, namely that the prototype methods don't have access to these "private" properties.

In your specific example though, normalize could as well be defined outside the constructor function, since it does not depend on anything inside the constructor function:

var AuthHmac = AuthHmac || (function(_, CryptoJS) {

    var normalize = function(s) { return s.toLowerCase(); };

    function AuthHmac(options) {
        var options = options || {};
        this.additionalHeaders = options.additionalHeaders || {};
    };

    AuthHmac.prototype.prepare = function(request) {
        request.headers = request.headers || {};

        _.each(this.additionalHeaders, function(value, name) {
            request.headers[normalize(name)] = value;
        });
    };

    return AuthHmac;

})(_, CryptoJS);

Upvotes: 1

karaxuna
karaxuna

Reputation: 26940

var AuthHmac = AuthHmac || (function(_, CryptoJS) {

function normalize(s) { return s.toLowerCase(); }

function AuthHmac(options) {
    var options = options || {};

    this.additionalHeaders = options.additionalHeaders || {};
};

AuthHmac.prototype.prepare = function(request) {
    request.headers = request.headers || {};

    _.each(this.additionalHeaders, function(value, name) {
        request.headers[normalize(name)] = value;
    });
};

return AuthHmac;

})(_, CryptoJS);

Upvotes: 1

Bergi
Bergi

Reputation: 664630

No, not if that normalize function is scoped to the constructor function.

However, since your function does not need to be privileged (i.e. have access to the constructor's local variables), you can easily put it outside and it still will be private to your module:

var AuthHmac = AuthHmac || (function(_, CryptoJS) {

    function normalize(s) { return s.toLowerCase(); }

    function AuthHmac(options) {
        var options = options || {};

        this.additionalHeaders = options.additionalHeaders || {};
    };

    AuthHmac.prototype.prepare = function(request) {
        request.headers = request.headers || {};

        _.each(this.additionalHeaders, function(value, name) {
            request.headers[normalize(name)] = value;
//                          ^^^^^^^^^
//    No `this.`! "private attributes" in JS are variables, not properties
        });
    };

    return AuthHmac;

})(_, CryptoJS);

Upvotes: 1

Related Questions