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

Mic*_*ael 3 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Way*_*ett 6

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

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

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

    //this does not work.
    alert(this.variable1);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

        //this does not work.
        alert(this.variable1);
    }
}
Run Code Online (Sandbox Code Playgroud)

JavaScript中的函数总是在某个上下文执行,该上下文this关键字引用.直接调用函数时(例如functionName():),该函数执行的上下文是全局window对象.所以,在里面_PrivateFunction2,this.variable1相当于window.variable1哪个可能不是你的意思.

你可能想要引用当前的实例,myobjectthis指的是外面的_PrivateFunction2.您可以this通过在另一个变量中存储对它的引用来保留对内部作用域的访问:

var _this = this;

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

    //this does not work.
    alert(_this.variable1);
}
Run Code Online (Sandbox Code Playgroud)

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

接下来:

    function _PrivateFunction1() {
        //This does work though.  I am confused.
        _PrivateFunction2();
    }
Run Code Online (Sandbox Code Playgroud)

我想,这对你来说应该是最正常的部分.这里没什么奇怪的.只有一个常规函数调用另一个.不要被这些嵌套在里面的事实所迷惑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!");
}
Run Code Online (Sandbox Code Playgroud)

这里this确实是指myObject,假设 - 这是一个重要的假设 - myObjectnew运算符调用,如下所示:

var obj = new myObject();
Run Code Online (Sandbox Code Playgroud)

如果它被称为这样:

var obj = myObject();
Run Code Online (Sandbox Code Playgroud)

然后this将引用该window对象,就像它对我们之前看到的函数所做的那样.关键的一点是价值this不固定.它取决于函数的调用方式.甚至有办法明确地将它设置为任意对象.

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

var obj = new myObject();
obj.function1();
Run Code Online (Sandbox Code Playgroud)

写作object.method()设置thisobject里面method.

那怎么this.function1能打电话_PrivateFunction1()?正如我们之前在this嵌套函数中保存使用值时所看到的那样,_PrivateFunction1()只是在this.function1词法范围中定义的另一个对象,因此它可以像_this以前一样使用它.

而且由于关闭,这些私有变量在myObject返回后很久仍然存在.

脚注:因为new在实例化对象时未能使用会在没有警告的情况下如此惊人地破坏事物,因此将您打算用作构造函数的函数的名称大写是一种良好的做法.所以myObject应该真的MyObject.

  • 谢谢你更冗长的答案.我有CS学位所以它有帮助.由于我总是研究Java/C#,'this'关键字,根据使用对象内部,真的让我迷惑了javascript.有了这个我应该更好的javascript!谢谢哥们儿 (2认同)