【问题标题】:use module global scope to define private class fields accessible from prototype使用模块全局范围来定义可从原型访问的私有类字段
【发布时间】:2015-08-08 04:13:15
【问题描述】:

如果构造函数和它的原型定义在同一个模块中,比如 AMD 模块,是否可以将模块的类私有字段设为全局以便在原型中访问,而不是在构造函数中使用下划线定义它们?

这样更好吗:

define(function (require) {
    "use strict";

    var steps = 0;

    function Constructor(_steps) {
        steps = _steps;
    }

    Constructor.prototype.go = function () {
        steps += 1;
    };

然后这个:

define(function (require) {
    "use strict";

    function Constructor(_steps) {
        this._steps = _steps;
    }

    Constructor.prototype.go = function () {
        this._steps += 1;
    };

?

【问题讨论】:

  • 这两种解决方案是不同的。您无法比较它们,因为它们的行为不同。
  • 也许你的意思是后者Constructor.prototype._ = {}; function Constructor(_steps) { this._.steps = _steps; }
  • @Maximus 你创建了多个类的实例吗?如果是,它们是否共享相同的steps 变量值?
  • 如果是单例,那么没有理由使用构造函数。
  • @Maximus 但它没有正式的要求。一切基于约定的东西——都是基于约定的。您可能会得到一些有用的 cmets/answers,但它们并不能直接解决您的问题,因为只有您才能回答。

标签: javascript


【解决方案1】:

TL;DR:并不重要(这只是一个次要的实现细节)

两种不同的解决方案。一个不一定比另一个“更好”,它们只是有不同的用例。

如果您使用的是构造函数/原型模式,那么从面向对象的意义上讲,在实例本身上设置构造函数参数是有意义的(使用this.<whatever-prop>)。如果您决定仅出于副作用而使用构造函数(通过根据传递给构造函数的参数设置someModuleVariable),它可能会不必要地混淆代码。

然而,拥有一个可供整个模块访问的“私有”变量是一种极其常见的模式......例如,当使用单例对象时,因为在离开函数的执行上下文时,作用域变量永远不会被破坏,该模块仍然可以查询该“模块本地”变量。

唯一让我犯错的是使用构造函数只是为了它的副作用......当构造函数的主要目的之一是隐式设置属性时,我为什么要使用构造函数?实例?

为了区分这两个想法,一个常见的模式是在原型内部使用init 方法,因为那是一个很好的地方来隐藏你想要的所有副作用。例如,可以建议这样做:

var Module = (function() {
  var somethingPrivate;

  function SomeObject(someProp) {
    // rely on the constructor to set instance properties
    this.someProp = someProp;
  }

  SomeObject.prototype = {
    init: function(_somethingPrivate) {
      // all of your side effects in here, such as:
      somethingPrivate = _somethingPrivate;
    }
  };

  return SomeObject;
}());

var module = new Module('Hello world! I belong to the instance');

module.init('I am a module-specific variable!');

当然,这并不是说在某些情况下您可能不希望依赖构造函数来获得其副作用。但是在您给出的示例中,它甚至看起来都不需要构造函数(尽管我理解该示例只是为了演示问题而设计的)。

您在何处以及如何使用_ 下划线大多无关紧要,仅作为旁注。它们在某些情况下很好,比如区分伪私有属性和“公共”属性,但我认为这更像是一种约定,而不是一成不变的模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    相关资源
    最近更新 更多