4

我正在开发一个规模较大的 JS 应用程序,我想将一些常用功能分解为一个实用程序类。但是,我不太清楚我应该如何去做。

例如,假设我有一堆基于形状的类需要调用实用程序类中的函数:

// Triangle class
Triangle.prototype = new Shape();
Triangle.prototype.constructor = Triangle;

function Triangle() {...}
Triangle.prototype.drawOutline = function() {
  var outline = Utility.canvas.trace(this._canvas); // Trace the shape.
  this._viewport.drawImage(outline, 0, 0); // Draw the traced outline.
}

// Circle class
Circle.prototype = new Shape();
Circle.prototype.constructor = Circle;

function Circle() {...}
Circle.prototype.drawOutline = function() {
  var outline = Utility.canvas.trace(this._canvas); // Trace the shape.
  this._viewport.drawImage(outline, 0, 0); // Draw the traced outline.
}

Utility在全局级别实例化类是否有意义?我觉得它上面应该有一个额外的级别,比如Application我会有Application.Utility,Application.UI等等。不幸的是,走这条路会迫使每个专门的形状类知道更大的程序结构是什么(因此它可以引用Application.Utility),这不是很好。

有没有更好的首选方式让专门的 JS 类使用未继承的通用类函数?


编辑:说我试图将其与C++ 或 Java中的#includeor语句联系起来可能会有所帮助。import在 JS 中解决这个问题的最佳方法是什么?

4

4 回答 4

3

假设您将所有代码包装在一个匿名函数中,那么我通常做的只是创建一个对象(命名空间)并将所有实用程序放在那里:

;(function(){

  var Utils = {
    triangle: function () { ... },
    circle: function () { ... }
  }

}())

然后,每当您使用它时,您只需这样做Utils.circle(...),您就知道何时使用 utils,并且很容易跟踪它们,添加新的等等。

说我试图将其与来自 C++ 或 Java 的 #include 或 import 语句联系起来可能会有所帮助。在 JS 中解决这个问题的最佳方法是什么?

在这种情况下,最简单的方法是创建一个concat.sh文件或类似文件和一个start.jsend.js添加其间的所有内容。

开始.js

;(function(){

实用程序.js

var Utils = {
  triangle: function () { ... },
  circle: function () { ... }
}

end.js

}())

连接.sh

当然,秩序很重要。

#!bin/bash
cat start.js utils.js end.js > out.js

如果您喜欢 node.js,请查看grunt,它只需很少的配置即可为您完成所有这些工作。

否则,对于更高级的东西,请使用 CommonJS 模块。

于 2012-07-03T00:26:20.707 回答
1

命名空间的最大原因是避免库之间的冲突。就我个人而言,我用 dt 为我写的所有内容添加前缀。所以我有 dt.Utility。选择一个前缀并使用它。=)

于 2012-07-03T00:21:44.093 回答
1

问题实际上可能是实用程序类,实际上不应该是实用程序类。也许最好做这样的事情:

// Triangle class
Triangle.prototype = new Shape();
Triangle.prototype.constructor = Triangle;

function Triangle() {...}
Triangle.prototype.drawOutline = function() {
}

// Circle class
Circle.prototype = new Shape();
Circle.prototype.constructor = Circle;

function Circle() {...}
Circle.prototype.drawOutline = function() {
}

function OutlineDrawer(shape)
{
    this.shape = shape;
}

OutlineDrawer.prototype.draw(viewport)
{
    var outline = Utility.canvas.traceShape(this.shape.canvas()); // Trace the shape.
    viewport.drawImage(outline, 0, 0); // Draw the traced outline.
}

你对形状承担了很多责任。形状应该定义形状的特定实例的属性,但您可能应该使用不同的类来跟踪它们。您可能希望将相同的形状绘制到不同的视口中(例如,将其保存到文件中),或者使用不同的算法来绘制相同的场景(调整速度、性能和质量)。ETC...

于 2012-07-03T00:39:31.633 回答
0

和其他人一样的答案。

将您的原型放在一个全局对象中(我知道,它不是很推荐,但它是一种特殊情况)。


// Utils.js

// treat this global object as a "namespace" or "module"
var Utils = 
{

  // Triangle class
  Triangle.prototype = new Shape();
  Triangle.prototype.constructor = Triangle;

  function Triangle() {...}
    Triangle.prototype.drawOutline = function() {
    var outline = Utility.canvas.traceShape(this._canvas); // Trace the shape.
    this._viewport.drawImage(outline, 0, 0); // Draw the traced outline.
  }

  // Circle class
  Circle.prototype = new Shape();
  Circle.prototype.constructor = Circle;

  function Circle() {...}
    Circle.prototype.drawOutline = function() {
    var outline = Utility.canvas.traceShape(this._canvas); // Trace the shape.
    this._viewport.drawImage(outline, 0, 0); // Draw the traced outline.
  }
} // var Utils

// anotherfile.js

var MyTriangle = new Utils.Triangle();
var MyCircle  =  new Utils.Triangle();

这个技巧,它被称为“模块软件设计模式”。

于 2012-07-03T00:54:49.683 回答