模块中的javascript私有内部函数,可以访问“this”范围

时间:2012-11-27 17:24:09

标签: javascript function scope

  

可能重复:
  Javascript outer scope variable access

我有一个类似于下面的javascript模块。我遇到的主要问题是如何从私有someOtherFunc访问“this”范围内的变量。有没有办法在私人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私有

6 个答案:

答案 0 :(得分:2)

忘记我之前的回答。您可以只需添加的私有版本即可。

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

答案 1 :(得分: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.myIntpublicData,它们将不再相等。


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

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;
}());

现在你有“私人”功能,只写一次(即:你节省内存),但任何实例都可以使用这些功能。

以下是捕获:
由于范围和闭包的工作原理,静态函数具有 NO 访问实例中 的值(函数) inside可以访问静态函数,而不是相反的方式。)

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

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

    privateFunc = function () {
        var string = static_helper(privateString);
        privateString = string;
        //...
    };

答案 2 :(得分: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 Demo

答案 3 :(得分:1)

我认为您正在寻找的是一种封装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 here

我希望这会有所帮助。

答案 4 :(得分:0)

return没有MyObj任何内容。

return this;

应该修复它。

答案 5 :(得分:0)

使用bind方法:

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