Javascript 使用模块全局范围定义可从prototype访问的私有类字段
如果构造函数及其原型是在同一个模块(比如AMD模块)中定义的,那么可以将类私有字段设置为全局字段,以便在原型中访问该模块,而不是在构造函数中用下划线定义它们吗 那么这是否更好:Javascript 使用模块全局范围定义可从prototype访问的私有类字段,javascript,Javascript,如果构造函数及其原型是在同一个模块(比如AMD模块)中定义的,那么可以将类私有字段设置为全局字段,以便在原型中访问该模块,而不是在构造函数中用下划线定义它们吗 那么这是否更好: define(function (require) { "use strict"; var steps = 0; function Constructor(_steps) { steps = _steps; } Constructor.prototype.go
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;
};
?TL;DR:其实没什么(只是一个小的实现细节)
两种不同的解决方案。一个不一定比另一个“更好”,它们只是有不同的用例
如果您使用的是构造函数/原型模式,那么在面向对象的意义上,在实例本身上设置构造函数参数是有意义的(使用this.
)。当您决定仅出于副作用而使用构造函数时(通过基于传递给构造函数的参数设置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!');
当然,这并不是说在某些情况下,您可能不希望依赖构造函数来实现其副作用。但在您给出的示例中,它看起来甚至不需要构造函数(尽管我知道这个示例只是为了演示问题而设计的)
在哪里以及如何使用
。
下划线基本上是不相关的,只是作为旁注。在某些情况下,它们很好,比如区分伪私有财产和“公共”财产,但我认为这更像是一种惯例,而不是一成不变的模式。这两种解决方案是不同的。您无法比较它们,因为它们的行为不同。在后者中,您可能指的是Constructor.prototype.\u={};函数构造函数(_steps){this._.steps=_steps;}
?@Maximus您是否创建了该类的多个实例?如果是,它们是否共享相同的步骤
变量值?如果是单例,则没有理由使用构造函数。@Maximus,但它没有正式的要求。一切以约定为基础的东西都是以约定为基础的。你可能会得到一些有用的评论/答案,但它们不会直接回答你的问题,因为只有你才能回答。