JavaScript:如何使用实例变量

时间:2012-07-31 11:38:49

标签: javascript oop

为什么这不能按预期工作。 (见预期评论)

var Module = function () {
    var public_instance_var;

    function doStuff () {
        Module.doOtherStuff();
        console.log(public_instance_var); // expected: true, but logs undefined
    };

    function doOtherStuff() {
        public_instance_var = true;
    };

    return {
        public_instance_var: instance_var,
        doStuff: doStuff,
        doOtherStuff: doOtherStuff
    }
}();

Module.doStuff();

更新:相应地修正了一些jAndy建议

3 个答案:

答案 0 :(得分:0)

这里有多个错误:

  • 您不会将DoStuff作为模块接口
  • 返回
  • instance_var未声明,可能意味着public_instance_var
  • doOtherStuff永远不会分配到Module,只需将其称为doOtherStuff();

固定代码:

var Module = function () {
    var public_instance_var;

    function doStuff() {
        doOtherStuff();
        console.log(public_instance_var); // expected: true, but logs undefined
    };

    function doOtherStuff() {
        public_instance_var = true;
    };

    return {
        doStuff: doStuff,
        public_instance_var: public_instance_var
    }
}();

Module.doStuff();

答案 1 :(得分:0)

像这样更改你的代码

var Module = function () {
    var public_instance_var;

    function doStuff () {
        doOtherStuff();
        console.log("var is ", public_instance_var); // expected: true, but logs undefined
    };

    function doOtherStuff() {
        public_instance_var = true;
    };

    return {
        public_instance_var: public_instance_var,
        doStuff : doStuff
    }
}();

Module.doStuff();
  • 您必须返回doStuff()函数(否则将在其外部未定义)和public_instance_var而不是instance_var
  • 您需要执行doOtherStuff()而不必添加前缀Module.

答案 2 :(得分:0)

这段代码的作用是,简单地说:创建并运行一个函数并将其返回值赋给变量:Module。返回值是一个具有1个属性的对象:public_instance_var,指向变量instance_var,或者(在纠正错误后:public_instance_var)。声明了此变量,但未实例化。因此返回值如下所示:

Module.public_instance_var = undefined

最后一行Module.doStuff();不会有效:模块是没有方法的对象。当匿名函数返回时,您声明的函数将被垃圾回收。如果要访问这些函数,则需要将它们包含在return语句中。一般来说,阅读闭包,对象构造函数和设计模式,但我会说你所追求的代码看起来像这样:

var Module = (function()
    var public_instance_var;
    function doStuff () {
        this.doOtherStuff();
        console.log(public_instance_var); // expected: true, but logs undefined
    };
    function doOtherStuff() {
        public_instance_var = true;
    };
    return {
        public_instance_var: public_instance_var,
        doStuff: doStuff,
        doOtherStuff: doOtherStuff
    };
})();

当然,这种方式你的变量public_instance_var是一个公共属性,所以我猜你真正要做的就是模拟私有属性和方法。在这种情况下,您可能会得到与此类似的代码:

var Module = (function()
{
    var public_instance_var;
    return {
        //public_instance_var: public_instance_var, remove this line
        //the closure will preserve access to the variable
        doStuff: function ()
        {
            this.doOtherStuff();//this, you're referencing the object's property
            console.log('here I am');
        },
        doOtherStuff: function ()
        {
            public_instance_var = true;
            //this won't work anymore:
            //this.public_instance_var = true;
        };
    }
})();

Module.doStuff()现在记录here I am,但doOtherStuff现在也是公共方法。以下是您可以选择解决问题的方法:

var Module = (function()
{
    var public_instance_var;
    function doOtherStuff ()
    {
        public_instance_var = true;
    };
    return {
        //public_instance_var: public_instance_var, remove this line
        //the closure will preserve access to the variable
        doStuff: function ()
        {
            doOtherStuff();//don't use this here, but the reference to the function exists thanks to closure
            console.log('here I am');
            console.log(public_instance_var);//logs true
        }
    };
})();

这些只是使用闭包和返回对象的函数可以做的一些非常强大的功能。
只要看几篇文章,比如this一篇,那里有更好的文章。谷歌的术语power constructors