2

我正在阅读关于 d3 中可重用图表的本教程,在第一个“配置”部分中,作者描述了两种制作图表功能的方法:

// Method 1
function chart(config) {
  // generate chart here, using `config.width` and `config.height`
}

// Method 2
function chart(config) {
  return function() {
    // generate chart here, using `config.width` and `config.height`
  };
}

他建议使用第二种方法而不是第一种方法,因为

但是,调用者必须同时管理图表函数(假设您有多种类型的图表可供选择)和配置对象。要将图表配置绑定到图表函数,我们需要一个闭包。

不过,我不明白这个解释。方法2相对于第一种方法有什么优势?

4

2 回答 2

2

这是关于管理信息的。在第一种情况下,如果要更改图表的配置,调用者必须记住config必须传递给chart

chart(config);
config.xy = 42;
// update the chart, calling chart again
chart(config);

现在,如果有多个可能不同的图表(以及因此不同的图表函数,如barchartlinechart等),调用者必须记住将哪个配置传递给哪个函数。

如果图表的“类型”以某种方式是独立的,那会更容易。在第二个示例中,您返回对知道如何更新刚刚创建的图表的函数的引用。因此,您可以在不知道它是由哪个函数创建的情况下更新图表:

var myChart = chart(config);
config.xy = 42;
// update the chart
myChart();

这似乎是 D3 使用的一种方法,但您也可以使用面向对象的方法,即创建一个适当的Chart构造函数来封装渲染和更新图表的逻辑。

于 2012-09-30T20:08:01.327 回答
1

这是我发现的一种方法,它甚至比您列出的两种方法还要好——我从 d3 源代码中获得了一些东西:

function chart() {
    var width, height;

    function display() {
        console.log("My dimensions are: (" + width + " x " + height + ").");
    }

    display.width = function(value) {
        if (!arguments.length) return width;
        width = value;
        return display;
    };

    display.height = function(value) { 
        if (!arguments.length) return height;
        height = value;
        return display;
    };

    return display;    
}

var config = {width: 5, height: 10},
    myChart = chart().width(config.width).height(config.height);

console.log("Width:", myChart.width());   // Width: 5
console.log("Height:", myChart.height()); // Height: 10
myChart(); // My dimensions are (5 x 10).
myChart.height(5);
myChart(); // My dimensions are (5 x 5).
于 2012-09-30T23:21:44.283 回答