1

Why does the marked line fail to find protectedACMember?

var Module = (function (ns) {

    function AbstractClass() {
        this.protectedACMember = "abstract";

        this.abstractPublicACMethod = function (input) {
            this.methodToImplement();                   
        }
    }

    ConcreteClass.prototype = new AbstractClass();
    function ConcreteClass(){
        var privateCCMember = "private CC";

        var privateCCMethod = function(){
            alert(this.protectedACMember); // cant find protectedACMember
        }

        this.methodToImplement = function(){ 
            privateCCMethod();
            console.log('Implemented method '); 
        }

    }

    ns.ConcreteClass = ConcreteClass;   

    return ns;

})(Module || {});

//somewhere later
var cc = new Module.ConcreteClass();
cc.abstractPublicACMethod();

are there any good patterns for simulating private, protected and public members? Static/non-static as well?

Queequeg
  • 2,824
  • 8
  • 39
  • 66

3 Answers3

1

You should change that part of code like this:

    var self = this;
    var privateCCMethod = function(){
        alert(self.protectedACMember); // this -> self
    }

This way you get the reference in the closure.

The reason is, that "this" is a reserved word, and its value is set by the interpreter. Your privateCCMethod is an anonymous function, not the object property, so if you call it simply by privateCCMethod() syntax, this will be null. If you'd like "this" to be bound to something specific you can always use .call syntax, like this:

privateCCMethod.call(this)
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Marek Kowalski
  • 1,782
  • 9
  • 11
  • what if I wrote `function privateCCMethod() {...}` - would it be a property of the object then? – Queequeg Jan 29 '13 at 14:19
  • No. In the code from your example "methodToImplement" is the property. This is one way of doing it. The other, would be to define it like ConcereteClass.prototype.privateCCMethod = function() {...}. – Marek Kowalski Jan 29 '13 at 15:57
0

It fails to find protectedACMember because what the this keyword means changes when you enter the function privateCCMethod. A common practice is to store the outer this for use inside the functions:

function ConcreteClass(){
    var privateCCMember = "private CC";

    // store the outer this
    var that = this;
    var privateCCMethod = function(){
        alert(that.protectedACMember);
    }
    ...

The rest of your questions are fairly loaded and should probably be posted as a separate question.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
jbabey
  • 45,965
  • 12
  • 71
  • 94
  • `this` is always the nearest enclosing function? what if I skipped `this` and simply wrote `alert(protectedACMember)`? – Queequeg Jan 29 '13 at 13:58
  • @Queequeg it would look for a scoped variable named `protectedACMember` and would not find anything. `protectedACMember` is a property of the object. – jbabey Jan 29 '13 at 14:00
  • is setting the `that` variable better than using `func.call(this,...)` ? – Queequeg Jan 29 '13 at 14:12
  • @Queequeg yes; providing the proper context for `protectedACMember` is the responsibility of `privateCCMethod`, not the consumer of the function. – jbabey Jan 29 '13 at 14:19
  • I meant the call inside `methodToImplement` – Queequeg Jan 29 '13 at 14:43
0

Another way to ensure that this means what you want is to use bind. Bind allows you to ensure a function is called with a specific value of this.

Most newer browsers support it (even IE9!) and there's a workaround for those that don't.

Bind - MDN Documentation

jtheis
  • 916
  • 3
  • 12
  • 28