JavaScript中私有变量和实例变量的方法和变量范围

时间:2011-02-24 01:51:12

标签: javascript

我试图弄清楚这一点或在谷歌上搜索它,我只能找到如何创建对象,而不是功能如何工作。如果有人能向我解释封装的工作原理。

function myObject() {

    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!");
    }

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

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

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

3 个答案:

答案 0 :(得分:6)

如果我们按相反顺序行事,我想我可以更好地解释这一点。首先,我们定义一些函数:

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

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

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

这是非常正常的事情。唯一奇怪的是它们出现在另一个函数中,但这完全没问题。 JavaScript有function scope,这意味着函数内定义的所有变量都在新范围内定义。它们不会践踏全局命名空间。 JavaScript中的函数是first-class objects,这意味着它们可以像其他数据类型一样使用。它们可以嵌套,传递给函数,从函数返回等等。

然后我们遇到了一些麻烦:

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

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

JavaScript中的函数始终为executed in some contextthis关键字引用该函数。直接调用函数时(例如:functionName()),该函数执行的上下文是全局window对象。因此,在_PrivateFunction2内,this.variable1相当于window.variable1,这可能不是您的意思。

您可能想要引用myobject的当前实例,这是this_PrivateFunction2之外引用的内容。您可以通过在另一个变量中存储对它的引用来保留对内部作用域中this的访问权限:

var _this = this;

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

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

你应该注意到这里有一些微妙的东西。 _PrivateFunction2可以访问lexical scope中定义的变量,这就是它可以访问_this的原因。这在以后很重要。

接下来:

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

对于你来说,这应该是最正常的部分,我想。这里没什么奇怪的。只有一个常规函数调用另一个。不要被这些嵌套在myObject内的事实所困惑。这改变了他们所处的范围,但没有多少。

接下来我们定义一些实例变量和方法:

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!");
}

此处this确实引用myObject,假设 - 并且这是一个重要的假设 - 使用myObject运算符调用了new,如下所示:< / p>

var obj = new myObject();

如果它被这样调用:

var obj = myObject();

然后this将引用window对象,就像我们之前看到的函数一样。关键的一点是this的价值不固定。它取决于函数的调用方式。甚至还有set it to an arbitrary object明确的方法。

this内的this.function1值也将是myObject的当前实例,因为它最有可能像这样使用:

var obj = new myObject();
obj.function1();

object.method()内写thisobject设置为method

那么this.function1如何调用_PrivateFunction1()?正如我们之前看到的那样,在保存this的值以便在嵌套函数中使用时,_PrivateFunction1()只是在this.function1的词法范围中定义的另一个对象,因此它可供其使用就像_this早些时候一样。

并且because of closure这些私有变量在myObject返回后很久仍然存在。

脚注:由于在实例化对象breaks things so spectacularly without warning时未能使用new,因此将您打算用作构造函数的函数名称大写是一种良好的做法。因此myObject应该是MyObject

答案 1 :(得分:0)

您必须保存实际对象的副本,例如 here ,请注意var that = this

在chrome和FF中测试

答案 2 :(得分:0)

用于封装我更喜欢模块模式,如

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

现在,如果您尝试调用像

这样的私有方法
callPublic._private();//it will return not a function since its not been exposed

有许多其他模式来封装你的方法,但模块模式是最常见的。希望不会帮助你如何在javascript中封装数据。