寻找一种重构D3.js风格方法链模式的方法 [英] Looking for a way to refactor D3.js-style method chaining pattern

查看:201
本文介绍了寻找一种重构D3.js风格方法链模式的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在学习D3.js时,我遇到了博客文章,介绍了主要设计 - 模式后面是可重用的代码单元。我已经复制了下面的相关位代码。下面提供的模式的方式正是它在D3代码库和插件中使用的方式( example )。

While learning D3.js, I have come across the blog post explaining the main design-pattern behind it's reusable units of code. I have reproduced the relevant bit of code below. The way the pattern is presented below is exactly the way it is used in D3 codebase and plug-ins (example).

我的一个问题是,它有这么多的属性的复制粘贴。 JavaScript是一个功能语言,我想我可以重新考虑样板代码,但我不能想到一个办法。 arguments 和 value 参数很容易传递给一个公共函数,但是我找不到一种保存对 width height 属性的引用。

My one issue with this code is that it has so much copy-paste for the properties. JavaScript being a functional language, I thought I'd be able to re-factor the boilerplate code out, but I can't think of a way to do it. The arguments and value parameters are easy to pass to a common function, but I can't find a way to preserve a reference to the width and height properties.

function chart() {
  var width = 720, // default width
      height = 80; // default height

  function my() {
    // generate chart here, using `width` and `height`
  }

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

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

  return my;
}

事实上,这是如何在实际的D3代码库,不知道是否可以重新分解,但我希望这只是一个问题,这不是一个高优先级的问题(新的贡献者是这样做,因为这是如何做)。

The fact that this is how it's done in the actual D3 codebase, makes me wonder if re-factoring is possible, but I'm hoping that it's simply a matter of this not being a high priority issue (and new contributors are doing it this way, because that's how it was done before).

我正在寻找的是基本上用每个访问者的身体替换:

What I'm looking for is basically replacing every accessor's body with:

my.height = function(value) {
  return getSet(arguments, value, whatever);
};

还有一些调用的样板,但至少逻辑是集中的, 如果您定义 getSet ,则只有一个地方。

There is still some boilerplate for the call, but at least the logic is centralized and can be updated in only one place, if needed.

推荐答案

图表的范围,它也可以访问关闭的变量。问题是,你不能通过名称字符串访问这些变量(除非你使用某种 eval )。

If you define getSet in the scope of chart, it will have access to the closed over variables too. The problem is, you can't access those variables by name string (unless you use some kind of eval).

您可以通过将所有私有变量包含在未测试的对象中来避免:

You could avoid that by wrapping all your private variables in an object untested:

function chart() {
    var props = {
        width: 720, // default width
        height: 80 // default height
    }

    function my() {
        // generate chart here, using `width` and `height`
    }

    my.height = function(value) {
        // Call getSet with current my instance as this, 
        // 'height' as the first argument, then value
        return getSet.apply(this, arguments.slice().unshift('height'));
    };

    // Works just like your current accessors, on the props object
    function getSet(property, value) {
        if (arguments.length > 1) return props[property];
        props[property] = value;
        return this;
    }

    return my;
}

问题是这不比为每个属性编写几个类似的访问器。你当前的访问器使私人变量虚拟公开,所以为什么不放弃他们并使用公共变量?

The problem is this is not much shorter than writing several similar accessors for each property. Your current accessors make the private variables virtually public, so why not just ditch them and use public variables instead?

这篇关于寻找一种重构D3.js风格方法链模式的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆