如何创建封装的';类别';用JavaScript?

如何创建封装的';类别';用JavaScript?,javascript,class,encapsulation,Javascript,Class,Encapsulation,在JavaScript中,类通常通过构造函数进行仿真。然而,我很好奇如何创建一个封装类,即一个将其部分成员保持私有的类 创建“类”的常见方法如下: function MyClass(parameter) { this.value = parameter; } MyClass.prototype.myPublicFunction = function() { console.log("About to run private function."); myPrivateF

在JavaScript中,类通常通过构造函数进行仿真。然而,我很好奇如何创建一个封装类,即一个将其部分成员保持私有的类

创建“类”的常见方法如下:

function MyClass(parameter) {
    this.value = parameter;
}

MyClass.prototype.myPublicFunction = function() {
    console.log("About to run private function.");
    myPrivateFunction();
};

MyClass.prototype.myPrivateFunction = function() {
    ...
};
如您所见,在本例中,
myPrivateFunction
实际上是公共的。我见过的解决此问题的一种方法如下:

function MyClass(parameter) {
    this.value = parameter;

    this.myPublicFunction = function() {
        console.log("About to run private function.");
        myPrivateFunction.call(this);
    }

    function myPrivateFunction() {
        ...
    }
}
这是有效的<代码>myPrivateFunction无法从外部访问。但是这种方法有一个问题——这个“类”中的所有函数都将跨实例复制,而不是通过
原型
共享。在任何地方使用
privateFunction.call(this)


非职能成员也是如此。如何在类中定义私有实例成员?什么是最好的,什么是最常见的方法?简单地依赖命名约定(例如以
\uu
开头的私有函数名)是否可以接受?

您可以创建一个作用域来隐藏具有自动执行函数的私有函数

比如:

但是,只有在声明了
MyClass
之后才需要使用它,因为现在它是一个函数表达式,而不是一个函数语句,但是
MyClass
的所有实例都将共享同一个
myPrivateFunction
实例。但是您需要使用
Function.prototype.call
(如
myPrivateFunction.call(this,'arg_a','arg_b');
来获取
this
关键字的值以匹配您的实例。 如果只执行
myPrivateFunction('arg_a,'arg_b');
关键字
将指向全局对象(
浏览器上的窗口
),或者
如果启用了
“严格模式”
,则
为空


请注意:在我自己的代码中,我不这样做,而是依赖于命名约定,如
MyClass.prototype.\u myPrivateFunction=function(){}
不使用某些框架时。

基本上没有办法在ES5中正确地执行此操作。您可以在ES6中执行此操作,但这意味着您只能支持最新的浏览器。James-您可以发布一个示例(答案?)。我不完全了解ES6中的功能,并对如何使用WeakMap来处理此问题感到好奇。我猜我越来越生疏=)也许以下内容会有所帮助,它有一个受保护的实例特定模式:
(function(){
    function myPrivateFunction(arg_a, arg_b) {
        /* ... */
        console.log("From priv. function " + this.value);
    }
    window.MyClass = function(parameter) {
        this.value = parameter;

        this.myPublicFunction = function() {
            console.log("About to run private function.");
            myPrivateFunction.call(this, 'arg_a', 'arg_b');
        }

    }
})();