3

I searched for this issue for quite a long time. Din't find any answer to satisfy my question. What I am trying is:

function myClass() {
    function privateFunction () {
        publicFunction();    //Error
    }
}

myClass.prototype.publicFunction = function() {
    this.variable = 1;
}
myClass.prototype.publicFunction2= function() {
    return this.variable;
}

This is giving me error. I am not getting what the real problem is:

What I tried:

this.publicFunction();

Then:

myClass.publicFunction();

Then:

myClass.prototype.publicFunction();

This works but it overrides for each object. Acts as if it is static across different JS objects.

Veer Shrivastav
  • 5,434
  • 11
  • 53
  • 83
  • Use `bind` or a closure for the `this` value of your `myClass` in `privateFunction`. Or you could even use `call`. So the problem is the scope of the `this` value that you want to use for `this.publicFunction()` – Xotic750 Feb 06 '15 at 12:58
  • possible duplicate of [How to access the correct \`this\` / context inside a callback?](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) – Scimonster Feb 06 '15 at 13:03

4 Answers4

3

You haven't declared the prototype functions correctly. You are also missing the this keyword when calling the function publicFunction.

The private function (privateFunction) is not a member of the class, so if you want to call it as a function, you have to specify the context for it.

function myClass() {
    function privateFunction () {
        this.publicFunction();
    }

    privateFunction.call(this);
    document.write(this.publicFunction2()); // show value in Stackoverflow snippet
}

myClass.prototype.publicFunction = function() {
    this.variable = 1;
}

myClass.prototype.publicFunction2 = function() {
    return this.variable;
}

var myClassPrototype = new myClass();
Zak The Hat
  • 317
  • 1
  • 5
  • 15
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Check my edit. I tried this. but unfortunately was not working. [Here](http://jsfiddle.net/srivastaveer/dg1negkb/) is the complete code what I am trying to do.. quite long. but easy to understand – Veer Shrivastav Feb 06 '15 at 13:05
  • `this.publicFunction()` is saying: `undefined is not a function` – Veer Shrivastav Feb 06 '15 at 13:08
  • @VeerShrivastav: I edited the code right after posting it, it looks like you have the code before the edit. Update the page and try it. In your User class you are calling for example `User.prototype.setEmpId([userKey]);` in the `formUserObjectFromArguments` function. That will call it as a method of the prototype object, not as a method of the User object. If you want to call the local function as a method you would use `formUserObjectFromArguments.call(this)`, that allows you to call `this.setEmpId([userKey]);` in the function. – Guffa Feb 06 '15 at 13:14
2

Wouldn't a closure be enough?

First, I'd rename myClass to MyClass by convention

function MyClass() {
    var myInstance = this;

    function privateFunction () {
        // closure 
        myInstance.publicFunction();
    }
}

MyClass.prototype.publicFunction = function() {
    this.variable = 1;
}
MyClass.prototype.publicFunction2= function() {
    return this.variable;
}

Now you should be able to instanciate it this way

var myInstance = new MyClass();

Now you can see that privateFunction is never called, and it woud be a bit redundant to call it, but I just tried to show how to technically achieve it.

axelduch
  • 10,769
  • 2
  • 31
  • 50
0

You aren't accessing it because it's inside a private function. Try it like this:

function myClass() {
    function privateFunction () {

    }

    this.publicFunction = function() {
         alert('ok')
    }

}

then if you do

var obj = new myClass()
obj.publicFunction()

you can see the alert

In order to inherit the class you will need some other things. Here is a complete example.

Now here is the relevant js code. Put it in a file to test it:

function Operators() {
    //mandatory
    var self = this

    //private
    var IPT_X = '#x'
    var IPT_Y = '#y'

    //public
    this.x = 0
    this.y = 0    

    this.showOperators = function() {
        //use of a private property (IPT_X) and a public property (this.x)
        $(IPT_X).val(this.x)
        $(IPT_Y).val(this.y)
    }

    this.clean = function() {
        this.x = 0
        this.y = 0
        // call to a local public method 
        this.showOperators()
    }

    this.updateOperators = function(_x, _y) {
        // use of a public property when call from
        // derived class method is necessary
        self.x = _x
        self.y = _y
    }
}

function Randomizer() {
    // mandatory for derived classes
    Operators.call(this)
    // mandatory for overloaded methods with call to the inherited method
    var parentUpdateOperators = this.updateOperators
    var self = this

    // private
    function getRandomNumber() {
        return Math.round(Math.random() * 1000)
    }

    // public
    this.updateOperators = function(_x, _y) {
            // call to inherited method of superior class
        parentUpdateOperators(_x, _y)
            // call to method of superior class
            self.showOperators()
    } 

    this.populateRandomNumbers = function() {
        // call to public local method (this.updateOperators())
        // and to a local private method (getRandomNumber())
        this.updateOperators(getRandomNumber(), getRandomNumber())
    }

    // init
    this.populateRandomNumbers()
}
// Mandatory for derived classes. Allows access to superior classes with
// more than 2 levels of inheritance ("grandfather" classes)
Randomizer.prototype = Object.create(Operators.prototype)

function Operations() {
    Randomizer.call(this)
    var self = this

    //private
    var IPT_RES = '#res'
    var BTN_SUM =  '#sum'
    var BTN_SUBTRACT =  '#subt'
    var BTN_MULTIPLY =  '#mult'
    var BTN_DIVISION =  '#div'
    var BTN_CLEAN =  '#clean'
    var BTN_RAND =  '#rand'

    function calcSum() {
        return self.x + self.y
    } 
    function calcSubtraction() {
        return self.x - self.y
    } 
    function calcMultiplication() {
        return self.x * self.y
    } 
    function calcDivision() {
        return self.x / self.y
    } 

    function showRes(val) {
        $(IPT_RES).val(val)
    }

    //public
    this.sum = function() {
        // call to 2 local private methods
        showRes(calcSum())
    }
    this.subtract = function() {
        showRes(calcSubtraction())
    }
    this.multiply = function() {
        showRes(calcMultiplication())
    }
    this.division = function() {
        showRes(calcDivision())
    }

    // init
    $(BTN_SUM).on('click', function() { self.sum() })
    $(BTN_SUBTRACT).on('click', function() { self.subtract() })
    $(BTN_MULTIPLY).on('click', function() { self.multiply() })
    $(BTN_DIVISION).on('click', function() { self.division() })    
    $(BTN_CLEAN).on('click', function() { self.clean() })
    $(BTN_RAND).on('click', function() { self.populateRandomNumbers() })
}
Operations.prototype = Object.create(Randomizer.prototype)

var obj = new Operations()

If you're going to test it here is the html code:

X: <input id='x'>
<br>
Y: <input id='y'>
<br>
Res: <input id='res'>
<br>
<input id='sum' type='button' value='+'>
<input id='subt' type='button' value='-'>
<input id='mult' type='button' value='*'>
<input id='div' type='button' value='/'>
<input id='clean' type='button' value='C'>
<input id='rand' type='button' value='Rand'>

don't forget to add the jquery file.

Here is a JSFiddle with that code in it:

http://jsfiddle.net/vqqrf2cb/24/

Nelson Teixeira
  • 6,297
  • 5
  • 36
  • 73
0

Try this:

function myClass() {
  function privateFunction(obj) {
    obj.privilegedFunction1();
  };
  this.privilegedFunction1 = function () {
    this.variable = 1;
  };
  this.privilegedFunction2 = function () {
    privateFunction(this);
  };
}

myClass.prototype.publicFunction2 = function () {
    return this.variable;
}

var test = new myClass();
test.privilegedFunction2();
console.log(test.publicFunction2());

And this:

function myClass() {
  function privateFunction(obj) {
    obj.publicFunction1();
  };
  this.privilegedFunction2 = function () {
    privateFunction(this);
  };
}

myClass.prototype.publicFunction1 = function () {
  this.variable = 1;
}

myClass.prototype.publicFunction2 = function () {
    return this.variable;
}

var test = new myClass();
test.privilegedFunction2();
console.log(test.publicFunction2());

You may want to read some about public vs private vs privileged members in Javascript. Like this article: http://javascript.crockford.com/private.html

Key points:

  1. Public (prototype) members have no access to private.
  2. Privileged (this) members have access to private.
  3. Private function may access privileged and public members through the passed context parameter.
a1111exe
  • 641
  • 4
  • 18