使用闭包将配置绑定到函数

时间:2012-09-30 19:56:47

标签: javascript d3.js

我正在阅读d3中可重复使用图表上的this tutorial,在第一个“配置”部分,作者描述了两种制作图表功能的方法:

// 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相对于第一种方法有什么优势?

2 个答案:

答案 0 :(得分: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构造函数,该函数封装了渲染和更新图表的逻辑。

答案 1 :(得分: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).