模块中的javascript私有内部函数,可访问;这";范围

模块中的javascript私有内部函数,可访问;这";范围,javascript,function,scope,Javascript,Function,Scope,可能重复: 我有一个javascript模块,如下所示。我面临的主要问题是如何从privatesomeOtherFunc访问“this”范围中的变量。有没有办法访问私有someOtherFunc var mymodule = (function(){ return { MyObj : function() { this.myvar = 123; this.publicfunc = function() {

可能重复:

我有一个javascript模块,如下所示。我面临的主要问题是如何从private
someOtherFunc
访问“this”范围中的变量。有没有办法访问私有
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;
            };

        }
     }
}
我的想法是,我想做一些像


新建mymodule.MyObj().publicfunc
,但将
someOtherFunc
private

忘记我以前的答案。您只需添加此文件的私有版本即可完成此操作

请记住,在代码中,每次调用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;
    };
});

您不会
MyObj
返回任何内容

return this;
应该修复它。

使用绑定方法:

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

为什么不更谨慎地构建它呢

// 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.myInt
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 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;
        //...
    };

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

function MyObj(){

        var myvar = 123;

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

        var someOtherFunc = function(){

            alert(myvar);

        };            
}


var o = new MyObj();
o.publicfunc();
如果您需要公共访问
myvar
,那么创建一个公共getter/setter


我认为您需要的是一种封装
myvar
以进行更改的方法。当其他一些答案运行时,
myvar
通常保持为
123
,因为
mymodule
最初返回的对象保留该初始值

返回一个函数,该函数即使在修改后也会获取
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


我希望这有帮助。

但是现在其他函数是公共函数,对吗?我不希望MyObj的实例能够访问someOtherFunc@JeffStorey请参阅我答案中的更改。但是如果public_接口的每个实例都需要自己的secretData呢?然后将所有内部内容放在函数中并返回函数,除非还需要“静态”数据,以便在实例之间共享,在这种情况下,您可以在外部函数中定义“静态”变量,然后从返回的函数(生成实例)中引用它们。在这种情况下privateFunc可以访问secretData吗?(如果myModule的每个实例都有secretData)?你能举个例子说明这是怎么做到的吗?我希望编辑后的版本能有所帮助。简而言之:每个实例都需要自己的
privateFunc
副本。这会增加内存(除非您正在制作成百上千个内存),但允许私有方法访问私有数据。您还可以拥有任何实例都可以使用或修改的静态数据和静态方法***但是***静态方法无法访问私有数据,因此您必须提供参数并从中收集返回语句。
someOtherFunc.call(this)
而不是
someOtherFunc()
function MyObj(){

        var myvar = 123;

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

        var someOtherFunc = function(){

            alert(myvar);

        };            
}


var o = new MyObj();
o.publicfunc();
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