从原型定义的函数访问私有成员变量更新:使用ES6,有更好的方法:对于所有带有 ES5 的现代浏览器:

2022-08-30 01:27:30

有没有办法使“私有”变量(在构造函数中定义的变量)可用于原型定义的方法?

TestClass = function(){
    var privateField = "hello";
    this.nonProtoHello = function(){alert(privateField)};
};
TestClass.prototype.prototypeHello = function(){alert(privateField)};

这有效:

t.nonProtoHello()

但事实并非如此:

t.prototypeHello()

我习惯于在构造函数中定义我的方法,但由于几个原因,我放弃了这一点。


答案 1

不,没有办法做到这一点。这基本上是相反的范围界定。

构造函数内部定义的方法有权访问私有变量,因为所有函数都可以访问定义它们的作用域。

在原型上定义的方法不在构造函数的范围内定义,并且无法访问构造函数的局部变量。

您仍然可以使用私有变量,但是如果您希望在原型上定义的方法可以访问它们,则应在对象上定义 getter 和 setter,原型方法(以及其他所有内容)有权访问它们。例如:this

function Person(name, secret) {
    // public
    this.name = name;

    // private
    var secret = secret;

    // public methods have access to private members
    this.setSecret = function(s) {
        secret = s;
    }

    this.getSecret = function() {
        return secret;
    }
}

// Must use getters/setters 
Person.prototype.spillSecret = function() { alert(this.getSecret()); };

答案 2

更新:使用ES6,有更好的方法:

长话短说,您可以使用新的来创建私有字段。
这里有一个很好的描述:https://curiosity-driven.org/private-properties-in-javascriptSymbol

例:

var Person = (function() {
    // Only Person can access nameSymbol
    var nameSymbol = Symbol('name');

    function Person(name) {
        this[nameSymbol] = name;
    }

    Person.prototype.getName = function() {
        return this[nameSymbol];
    };

    return Person;
}());

对于所有带有 ES5 的现代浏览器:

您可以只使用闭包

构造对象的最简单方法是完全避免原型继承。只需在闭包中定义私有变量和公共函数,所有公共方法都将具有对变量的私有访问权限。

或者,您可以仅使用原型

在JavaScript中,原型继承主要是一种优化。它允许多个实例共享原型方法,而不是每个实例都有自己的方法。
缺点是每次调用原型函数时一不同的东西。
因此,任何私有字段都必须可以通过 访问,这意味着它们将是公共的。因此,我们只是坚持字段的命名约定。thisthis_private

不要费心将闭包与原型混合在一起

我认为你不应该将闭包变量与原型方法混合在一起。您应该使用其中一个。

使用闭包访问私有变量时,原型方法无法访问该变量。因此,您必须将闭包公开到 上,这意味着您正在以某种方式公开它。这种方法几乎没有什么好处。this

我应该选择哪一个?

对于非常简单的对象,只需使用带有闭包的普通对象即可。

如果你需要原型继承-用于继承,性能等-那么坚持使用“_private”命名约定,不要打扰闭包。

我不明白为什么JS开发人员如此努力地使字段真正私有。