【发布时间】:2013-06-06 21:28:42
【问题描述】:
我在很多项目中使用 D3 可视化库,发现自己为每个项目复制和粘贴了大量样板代码。例如,大多数项目都是这样开始的:
var margin = {top: 20, right: 10, bottom: 30, left: 60},
width = 960,
height = 500;
var svg = d3.select(container_id).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
在这种代码之后,每个项目都会出现分歧。 D3 的部分乐趣在于,您可以为每个新项目进行一些专门的、创造性的编码。
我想为样板代码编写一个轻量级的包装器,这样我每次都可以跳到有趣的部分,这样做我意识到我不太明白如何正确地制作一个复杂的、可重用的 Javascript 对象。这是我开始的:
var d3mill = function() {
var margin = {top: 20, right: 10, bottom: 30, left: 60},
width = 960,
height = 500;
var svg = d3.select(container_id).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
return {
svg: function() { return svg; },
call: function(f) { f(); }
};
};
我想我希望能够做到这一点:
var d3m = d3mill();
var test = function() {
console.log(svg);
};
d3.call(test);
我认为(希望)通过call() 传递函数会导致函数在d3mill 实例的闭包内触发,从而定义svg。
以上面svg() 函数的方式将闭包中的每个变量都暴露给外界将是巨大的浪费时间。允许外部函数在这里运行的正确方法是什么?
【问题讨论】:
-
如果使用
call作为属性名称,请注意不要将其与developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 混淆。出于这个原因,我不确定我会选择这个名字。 -
好点,谢谢。将在此处保持相同以避免与现有答案混淆,但已适当注明。
-
如果您有兴趣,这里有一个关于 javascript 设计模式的好资源:addyosmani.com/resources/essentialjsdesignpatterns/book 模块模式或构造器模式可能值得一看。
标签: javascript object d3.js closures