原型应该与自执行匿名函数一起使用

时间:2013-05-16 01:38:40

标签: javascript

我以前用C ++和Java编写了很多程序,并且现在更多地使用Javascript。

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

我也读过这篇文章,我发现它非常有用:

How Good C# Habits can Encourage Bad JavaScript Habits: Part 1

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

然而,这种模式不使用javascript原型。我想知道这两者能否或应该和解?

例如,我已经宣布了一个名为mycharts的“模块”,其中包含多个图表。第一张图是barChart。我有以下简化代码:

(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 || {}, $));

在这个例子中我有一个'class',barChart有三个'methods',barColor()和render()(public)和drawChart()(private)。没有使用javascript的prototype属性定义任何方法。

我的问题是:我是否应该使用原型或不使用原型?

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

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() {...};

但是对于'私人'方法来说,正确的方法是什么?我理解私有并没有真正执行,但上面的原始代码使得它们在“类”上下文之外的使用不方便,所以如果可能的话,我希望将我的私有方法保持为尽可能“私有”。

2 个答案:

答案 0 :(得分:3)

“应该”的标准是什么?

如果要创建多个实例,原型继承是好的,否则闭包(以及“模块模式”)对单身人士和“私人”成员都有好处。

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

javascript的优点在于,您可以在一个程序中使用各种OO模式,使用适合每种情况的最佳模式。这不是一个问题,而是在某种情况下最适合的问题。查看更受重视的库的代码,你会看到大多数(全部?)混合原型,模块和普通对象属性。

答案 1 :(得分:0)

如果你总是返回chart对象,那么你可以在prototype上定义这些方法一次,然后只返回一个以其为原型的新对象。