模块模式中的私有变量

Private Variables in Module Pattern

我不是很清楚private的概念,如果我仍然可以通过public方法访问它并重新定义模块的属性。我的意思是,我完全可以做到:

var aModule = (function() {

    var privateVar = 1;

    return {
        publicFunction: function() {
            return privateVar;
        }
    }

})();

aModule.publicFunction = function() {
    privateVar = function() {
        console.log('a new content');
    }
    privateVar();
};

aModule.publicFunction(); // 'a new content'

我知道如果我用 let 或 const 在 ES6 中写它是不可能的,因为它会给我错误尝试覆盖私有变量的值,但它在 ES5 中有什么意义?

您正在覆盖 public 函数并且无法访问模块私有变量

考虑以下创建为 aModule 的 属性 的新函数,它试图仅更改 var privateVar

的值

作用域因调用位置不同而不同,并且无法访问该私有变量

var aModule = (function() {

    var privateVar = 1;

    return {
        publicFunction: function() {
            return privateVar;
        }
    }

})();

aModule.newFunction = function() {
    // try to change privateVar in aModule 
    privateVar = 3
};

aModule.newFunction();

console.log(aModule.publicFunction()); //still 1 not 3
// here's where it actually ended up
console.log(window.privateVar)

私有变量不能被模块外部的代码或拥有私有变量的 class 访问或更改。

例如,您不能做 aModule.privateVar 并期望它会给您任何回报。

您的 publicFunction 就是 Java(和其他编程语言)世界所说的 "getter"。简单地说,它允许访问私有变量的值,但不允许对其进行写访问。

在你的最后一个例子中,你实际上并没有覆盖私有变量。您只是在 publicFunction 的范围内创建一个新变量并为其赋值。仅仅因为它也被命名为 privateVar 并不意味着它是相同的内存区域。

我已添加到您的代码中以证明这一点

var aModule = (function() {

        var privateVar = 1;

        return {
            publicFunction: function() {
                return privateVar;
            },
            getPrivateVar() {
                return privateVar;
            }
        }

    })();

    aModule.publicFunction = function() {
        privateVar = function() {
            console.log('a new content');
        }
        privateVar();
     };

     aModule.publicFunction(); // 'a new content'
     console.log(aModule.getPrivateVar()); //outputs 1

为了更详细地说明这是为什么,一切都与范围有关。 privateVar 存在于匿名函数的范围内。这个匿名函数 returns 一个对象,上面定义了几个函数。当函数被调用时,这个对象被分配给 aModule,但保留对 privateVar 的访问,因为它们共享范围。

但是,在该函数之外,我们处于不同的作用域,该作用域无法访问 aM​​odule 的变量,返回对象中公开的变量除外