【问题标题】:One attempt of private methods in JSJS中私有方法的一种尝试
【发布时间】:2014-10-07 20:43:29
【问题描述】:

我见过有人尝试在 JS 中实现私有方法。但是他们都有不同的问题,比如这个:JavaScript private methods

我相信我的尝试也存在一些问题。但是除了在严格模式下不允许开销和调用者之外,我的实现有什么问题? 您可以在 jsfiddle 中看到一个工作示例:http://jsfiddle.net/rabbit_aaron/oqpen8c8/17/

实现也贴在这里:

var CLASS = function () {
    this.publicFunctions = {};
    this.PROTOTYPE = {};
    var _class = function () {
        this.constructor.apply(this, arguments);
    };
    _class.prototype = this.PROTOTYPE;
    _class.prototype.validateAccess = CLASS.prototype.validateAccess;
    _class.prototype.constructor = function () {};
    _class.prototype.publicFunctions = this.publicFunctions;
    this.finalClass = _class;

    return this;
};

CLASS.prototype.validateAccess = function (caller) {
    if (this.publicFunctions[caller] !== caller) {
        throw 'Accessing private functions from outside of the scope';
    }
    return true;
};
CLASS.prototype.setConstructor = function (func) {
    this.PROTOTYPE.constructor = func;
};
CLASS.prototype.addPrivateFunction = function (name, func) {
    this.PROTOTYPE[name] = function () {
        this.validateAccess(this[name].caller);
        func.apply(this, arguments);
    };
    return this;
};

CLASS.prototype.addPublicFunction = function (name, func) {
    this.PROTOTYPE[name] = func;
    this.publicFunctions[this.PROTOTYPE[name]] = this.PROTOTYPE[name];
    return this;
};


CLASS.prototype.getClass = function () {
    return this.finalClass;
};

【问题讨论】:

  • 有些人只是在范围内创建一个变量并为其分配一个函数。非常私密。
  • 似乎很难维护。为什么不使用简单的模块模式?
  • 它只是给你的代码增加了一些复杂性,但对你的私有函数没有保护。因此,与例如相比,我没有看到任何真正的优势。以_ 为函数添加前缀,并在文档中使用jsdoc 将其标记为私有。
  • 如何从子类继承?在您的示例中,我可以看到继承自 CLASS 的 Person 类。如果我想创建一个继承自 PersonLadyGentleman 类怎么办?
  • 这个问题不应该发到codereview.stackexchange.com吗?

标签: javascript function oop private


【解决方案1】:

首先想到的是,在稍后加载的一些代码中执行以下操作非常简单:

instanceOfSubClass.validateAccess = function (caller) {
    return true;
}

这有效地覆盖了验证。几乎所有不涉及使用嵌套范围来隐藏变量的私有变量技巧都会遇到这个问题。当然,这是一件非常具体的事情,必须知道才能做,所以这取决于您要防止什么。如果您只是想在将来保护自己,那么这可能会很好,但是如果您发布的库将与您不编写的代码进行交互并且您希望确保它始终正常运行,那么这个不是要走的路。

【讨论】:

    【解决方案2】:

    我相信我的尝试也有一些问题。

    是的。

    但除了开销和调用者在严格模式下是不允许的

    我不会称之为问题,我会称之为不行。严格模式应该是默认模式。

    我的实现有什么问题?

    关于您将方法设为“私有”的方法:

    • 绕过您的措施很容易。像 @Austion 一样,您可以简单地覆盖 validateAccess 函数,但您也可以与公共 publicFunctions 对象混淆
    • 它只是隐藏方法,而不是字段。将非函数属性设为私有通常是更相关的目标,因为它们包含实例的(值得保护的)状态。
    • 它在没有Function::toString 反编译的引擎中不起作用(有一些旧的)。此外,它不适用于以编程方式创建(作为闭包)并共享同一主体的方法。

    您的实现中的一些可以修复的错误:

    • 私有方法不能return一个值
    • 私有方法不能调用其他私有方法,只有公共方法可以调用
    • this.constructor.apply(this, arguments); 是一个创建可设置构造函数的好主意。但是,它 a) 一旦你尝试继承就会严重失败(可以通过调用 _class.prototype.constructor 来修复)并且 b) 破坏了 fn.prototype.constructor == fn/Object.getPrototypeOf(instance)==instance.constructor.prototype 的经验法则

    请记住,只有通过use of closures 才能实现真正的隐私。

    【讨论】:

      猜你喜欢
      • 2020-08-02
      • 1970-01-01
      • 2010-11-21
      • 1970-01-01
      • 2012-03-01
      • 2013-07-23
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多