在学习 D3.js 时,我遇到了博客文章 http://bost.ocks.org/mike/chart/解释其可重用代码单元背后的主要设计模式。我复制了下面的相关代码。下面呈现的模式的方式正是在 D3 代码库和插件中使用的方式(example https://github.com/d3/d3-plugins/blob/master/rollup/rollup.js).
我对这段代码的一个问题是它有太多的属性复制粘贴。 JavaScript 是一种函数式语言,我认为我能够重构样板代码,但我想不出一种方法来做到这一点。这arguments
and value
参数很容易传递给通用函数,但我找不到一种方法来保留对width
and height
特性。
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 代码库中的完成方式,让我想知道重构是否可能,但我希望这只是一个不是高优先级问题的问题(新的贡献者正在这样做)方式,因为以前就是这样做的)。
我正在寻找的基本上是将每个访问器的主体替换为:
my.height = function(value) {
return getSet(arguments, value, whatever);
};
该调用仍然有一些样板,但至少逻辑是集中的,并且如果需要,可以仅在一处进行更新。
如果你定义getSet
在范围内chart
,它也可以访问封闭变量。问题是,您无法通过名称字符串访问这些变量(除非您使用某种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;
}
问题是这并不比为每个属性编写几个类似的访问器短多少。您当前的访问器使私有变量几乎成为公共变量,那么为什么不放弃它们并使用公共变量呢?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)