Method And Variable Scoping Of Private And Instance Variables In Javascript
Solution 1:
I think I can explain this better if we go in reverse order. First, we define some functions:
function _PrivateFunction1() {
//This does work though. I am confused._PrivateFunction2();
}
function _PrivateFunction2() {
alert("look! PrivateFunction1");
//this does not work.alert(this.variable1);
}
This is pretty normal stuff. The only thing that's weird is that they appear inside another function, but that's perfectly fine. JavaScript has function scope, which means that all variables defined inside a function are defined in a new scope. They do not trample on the global namespace. And functions are first-class objects in JavaScript, which means they can be used just like other data types. They can be nested, passed to functions, returned from functions, etc.
Then we run into some trouble:
function _PrivateFunction2() {
alert("look! PrivateFunction1");
//this does not work.alert(this.variable1);
}
}
Functions in JavaScript are always executed in some context which is referred to by the this
keyword. When you call a function directly (i.e. like this: functionName()
) the context in which that function executes is the global window
object. So, inside _PrivateFunction2
, this.variable1
is equivalent to window.variable1
which is probably not what you meant.
You probably wanted to refer to the current instance of myobject
which is what this
refers to outside of _PrivateFunction2
. You can preserve access to this
in an inner scope by storing a reference to it in another variable:
var _this = this;
function_PrivateFunction2() {
alert("look! PrivateFunction1");
//this does not work.alert(_this.variable1);
}
There's something subtle here you should notice. _PrivateFunction2
has access to the variables defined in its lexical scope, which is why it can access _this
. This will be important later.
Next up:
function _PrivateFunction1() {
//This does work though. I am confused._PrivateFunction2();
}
This should be the most normal-looking section to you, I would think. There's nothing strange going on here. Just one regular function calling another one. Don't be confused by the fact that these are nested inside myObject
. That changes the scope they're in, but not much else.
Next we define some instance variables and methods:
this.variable1 = "tst";
this.function1 = function() {
//Now this function works. A 'this' function to a private function is ok_PrivateFunction1();
//Here is error one, I cannot seem to call methods within the object//from. this.function2();
}
this.function2 = function() {
alert("look! function2!");
}
Here this
really does refer to myObject
, assuming -- and it's an important assumption -- that myObject
was called with the new
operator, like this:
var obj = new myObject();
If it had been called like this:
var obj = myObject();
Then this
would refer to the window
object, just like it did for the functions we saw earlier. The key takeaway is that the value of this
is not fixed. It's determined by the way in which the function is called. There are even ways to set it to an arbitrary object explicitly.
The value of this
inside this.function1
will also be the current instance of myObject
, because it will most likely be used like this:
var obj = new myObject();
obj.function1();
Writing object.method()
sets this
to object
inside method
.
So how is this.function1
able to call _PrivateFunction1()
? Just as we saw earlier when saving the value of this
for use inside a nested function, _PrivateFunction1()
is just another object defined in this.function1
's lexical scope, so it is available for its use, just as _this
was earlier.
And it's because of closure that these private variables are still alive long after myObject
has returned.
Footnote: Because failing to use new
when instantiating objects breaks things so spectacularly without warning, it's considered good practice to capitalize the names of functions you intend to be used as a constructor. So myObject
should really be MyObject
.
Solution 2:
You have to save a copy of the actual object like here note the var that = this
Tested in chrome and FF
Solution 3:
for encapsulation I would prefer module pattern like
var someMethod = function(){
var i,
length,
// public methodpublic = function(num1, num2){
return num1+num2;
},
//private method
_private = function(){};
//exposing the public methodreturn{
public:public
}
};
var callPublic = someMethod();
callPublic.public(20, 30);// call the public method and return 50
now , if you try to call that private method like
callPublic._private();//it will return not a function since its not been exposed
There are lot of other pattern to encapsulate your methods but module pattern is most common. Hope ot will help you how to encapsulate data in javascript.
Post a Comment for "Method And Variable Scoping Of Private And Instance Variables In Javascript"