2

可能重复:
Javascript 外部范围变量访问

我有一个如下所示的 javascript 模块。我遇到的主要问题是如何从私有访问“this”范围内的变量someOtherFunc。有没有办法this.myvar私下访问someOtherFunc

var mymodule = (function(){

    return {   
        MyObj : function() {

            this.myvar = 123;

            this.publicfunc = function() {
                someOtherFunc();
            };

            var someOtherFunc = function() {
                //this doesn't seem to work
                this.myvar = 456;
            };

        }
     }
}

这个想法是我希望能够做类似的事情

new mymodule.MyObj().publicfunc,但使someOtherFunc私有

4

6 回答 6

2

忘记我之前的回答。您可以通过添加 this 的私有版本来做到这一点

var mymodule = (function() {
    return {   
        MyObj : function() {
            this.myvar = 123;
            var that = this;

            this.publicfunc = function() {
                someOtherFunc();
            };

            var someOtherFunc = function() {
                that.myvar = 456;
            };
            return this;
        }
    };
});

请记住,使用您的代码,每次调用 MyObj 时都会得到一个新对象
所以这会做你想要的:

>var o = new mymodule().MyObj()
>o.myvar
123
>o.publicfunc()
>o.myvar
456

但不是这个

>var m = new mymodule()
>m.MyObj().myvar
123
>m.MyObj().publicfunc()
>m.MyObj().myvar
123

如果这不是你想要的,考虑做这样的事情

var mymodule = (function() {
    var myObj = null;
    this.MyObj = function() {
        if(myObj != null)
            return myObj;
        myObj = {};
        myObj.myvar = 123;

        myObj.publicfunc = function() {
            someOtherFunc();
        };

        var someOtherFunc = function() {
            myObj.myvar = 456;
        };
        return myObj;
    };
});
于 2012-11-27T17:32:20.803 回答
1

为什么不更刻意地建造它呢?

// this one returns an object used like:
// myModule.myInt; /* 456 */
// myModule.myFunc(); /* 124 */
var myModule = (function () {
    var secretData = 123,
        publicData = 456,

        publicFunc = function () { return privateFunc(secretData); },
        privateFunc = function (num) { return num + 1; },

        public_interface = {
            myInt  : publicData,
            myFunc : publicFunc
        };

    return public_interface;

}());

我经历了显式命名返回的公共对象的麻烦,但现在很清楚什么是公共的,什么不是公共的,然而,这些东西中的每一个都可以访问彼此的可变版本,除了一个例外如果你改变myModule.myIntor publicData,它们将不再相等。


为了演示我在下面的评论中的意思,使用它们自己的私有数据/方法创建多个实例,我只是添加了一层函数范围:

var myModule = (function () {

    var static_int = 789,

        makeInstance = function (/* any constructor values */) {
            var secretData = 123,
                publicData = 456,

                publicFunc = function () { return privateFunc(secretData); },
                privateFunc = function (num) {
                    console.log(static_int);
                    return num + 1;
                },

                public_interface = {
                    myInt  : publicData,
                    myFunc : publicFunc
                };

            return public_interface;
        };

    return makeInstance;
}());

你现在像这样使用它:

var newModule = myModule(/* instance parameters */);
newModule.myFunc();

...或者

var num = myModule(/* instance parameters */).myFunc();

如果你想节省内存,你可以在静态层中使用静态辅助函数:

var myModule = (function () {

    var static_int = 789,

        static_addOne = function (num) { return num + 1; },
        static_divideBy = function (dividend, divisor) { return dividend/divisor; },

        makeInstance = function (/* any constructor values */) {
            var secretData = 123,
                publicData = 456,

                publicFunc = function () { return privateFunc(secretData); },
                privateFunc = function (num) {
                    console.log(static_int);
                    return num + 1;
                },

                public_interface = {
                    myInt  : publicData,
                    myFunc : publicFunc
                };

            return public_interface;
        };

    return makeInstance;
}());

现在您拥有只编写一次的“私有”函数(即:节省内存),但任何实例都可以使用这些函数。

这里有一个问题:
由于作用域和闭包的工作方式,静态函数无法访问实例内部的值(内部的函数可以访问静态函数,而不是相反)。

因此,任何静态辅助函数都必须将值作为参数传递给它们,并且如果您要修改数字或字符串,则必须从该函数中返回值。

// inside of a private method, in any instance
var privateString = "Bob",

    privateFunc = function () {
        var string = static_helper(privateString);
        privateString = string;
        //...
    };
于 2012-11-27T17:35:51.557 回答
1

myvar使用关键字声明var,将其设为私有,然后在没有this.:的情况下访问它

function MyObj(){

        var myvar = 123;

        this.publicfunc = function() {
            someOtherFunc();
        };

        var someOtherFunc = function(){

            alert(myvar);

        };            
}


var o = new MyObj();
o.publicfunc();

如果您需要公共访问权限,myvar则创建一个公共 getter/setter。

jsFiddle 演示 ​</p>

于 2012-11-27T17:38:31.363 回答
1

我认为您正在寻找的是一种封装myvar更改的方法。当其他一些答案运行时,myvar通常会保持原样,123因为最初返回的对象 frommymodule持有该初始值。

返回一个myvar即使在修改后也能获得值的函数,我认为这对您的问题有帮助。

这是对我有用的代码:

var mymodule = (function(){
    var myvar = 123,
        publicfunc = function() { myvar = 456 },
        getMyVar = function() { return myvar; };

    return {
        someOtherFunc : publicfunc,
        myPublicVar : getMyVar
     };
}());

mymodule.someOtherFunc();
alert(mymodule.myPublicVar());​  //gives you 456

JSFiddle在这里

我希望这有帮助。

于 2012-11-27T17:52:18.893 回答
0

你什么都不returnMyObj

return this;

应该修复它。

于 2012-11-27T17:32:28.000 回答
0

使用绑定方法:

var someOtherFunc = function() {
     this.myvar = 456;
}.bind(this);
于 2012-11-27T17:32:42.450 回答