开发者

Method and variable scoping of private and instance variables in JavaScript

开发者 https://www.devze.com 2023-02-13 15:19 出处:网络
I have tried to figure this out or search for it on google, i can only find how to create objects, not exactly how functions work.If someone could explain to me how encapsulation works.

I have tried to figure this out or search for it on google, i can only find how to create objects, not exactly how functions work. If someone could explain to me how encapsulation works.

function myObject() {

    this.variable1 = "tst";

    this.function1 = function() {
        //Now this funct开发者_开发问答ion 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!");
    }

    function _PrivateFunction1() {
        //This does work though.  I am confused.
        _PrivateFunction2();
    }

    function _PrivateFunction2() {
        alert("look! PrivateFunction1");

        //this does not work.
        alert(this.variable1);
    }
}


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.


You have to save a copy of the actual object like here note the var that = this

Tested in chrome and FF


for encapsulation I would prefer module pattern like

var someMethod = function(){



     var i, 
         length,

     // public method
     public = function(num1, num2){
            return num1+num2;
     },

    //private method
     _private = function(){};

    //exposing the public method

     return{
       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.

0

精彩评论

暂无评论...
验证码 换一张
取 消