2

我以前用 C++ 和 Java 编写过很多程序,这些天越来越多地接触到 Javascript。

我一直在阅读 Javascript 中不同的类定义模式,并且对 javascript 的原型属性很熟悉(但不是很熟悉)。

我还阅读了这篇文章,我发现它非常有用:

良好的 C# 习惯如何鼓励不良的 JavaScript 习惯:第 1 部分

特别是向下滚动到自我执行匿名函数:第 2 部分(公共和私有)部分,我非常喜欢。

然而,这种模式没有使用 javascript 原型。我想知道两者是否可以或应该和解?

例如,我声明了一个名为 mycharts 的“模块”,其中包含多个图表。第一个图表是条形图。我有以下简化代码:

(function(mycharts, $, undefined) {
  mycharts.barChart = function(containerDiv, data) {

      // private variables specific to a given chart instance
      var chart = {};
      var _containerDiv = containerDiv;
      var _data = data;      
      var _barColor = 'blue';   // default color is blue

      // public getter/setter accessor
      chart.barColor = function(_) {
        if (!arguments.length) return _barColor;
        _barColor = _;
        return chart;
      };

      // public method
      chart.render = function() {    
        drawChart(_data.table, _data.values);
      };

      // private method
      function drawChart(table, values) {
        ...
      }

      return chart;
}(window.mycharts = window.mycharts || {}, $));

在这个例子中,我有一个“类”,barChart,它有三个“方法”,barColor() 和 render()(公共)和 drawChart()(私有)。没有一个方法是使用 javascript 的原型属性定义的。

我的问题是:对于这些方法中的任何一个或所有方法,我应该使用原型还是不使用?

更新:根据这里的答案和评论是客户如何使用这个模块:

var chart1 = mycharts.barChart('#chart1', data_set1)
                     .barColor('red');

var chart2 = mycharts.barChart('#chart2', data_set2)
                     .barColor('green'); 

chart1.render();
chart2.render();

是的,我更新了原始代码片段以返回图表(哎呀,我错过了那行)。因此,每次调用 mycharts.barChart() 时都会返回图表对象的各个实例。

更新 2:向原型添加“公共”方法似乎很简单。只需将其定义为与上面自执行匿名函数中最初描述的非常相似。例如:

chart.prototype.render() = function() {...};

但是对于“私有”方法,正确的方法是什么?我知道私有并没有真正强制执行,但是上面的原始代码使它们在“类”上下文之外的使用不方便,所以如果可能的话,我想尽可能地将我的私有方法保持为“私有”。

4

2 回答 2

3

你对“应该”的标准是什么?

如果要创建多个实例,原型继承很好,否则闭包(和“模块模式”)对单例和“私有”成员有好处。

请记住,javascript 中的“私有”不提供任何安全性,它只是为您不希望公开的值和方法提供便利(例如,您可能有旨在仅在对象上下文中工作的方法,并且'不要在外部使用,或者应该共享的值并且您不想传递它们)。

javascript 的美妙之处在于,您可以在一个程序中使用各种 OO 模式,并在每种情况下使用最适合的模式。这不是一个或另一个的问题,而是在特定情况下最适合什么。查看更受推崇的库的代码,你会发现它们中的大多数(全部?)混合了原型、模块和普通对象属性。

于 2013-05-16T03:40:57.837 回答
0

如果您总是返回该chart对象,那么您可以受益于prototype一次性定义这些方法并返回一个以该对象为原型的新对象。

于 2013-05-16T01:49:54.707 回答