![](/img/trans.png)
[英]JavaScript Prototype Functions Using Privileged Getter/Setter Functions?
[英]Sharing getter/setter functions across Javascript code
以下示例基于Mike Bostock的可重用图表建议 。
给定两个函数( bar()
和pie()
),每个函数都会生成不同种类的图表:
function bar() {
var width = 720, // default width
height = 80; // default height
function my() {
console.log('bar created: ' + width + ' ' + 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;
};
my.render = function() {
my();
return my;
};
return my;
}
function pie() {
var width = 720, // default width
height = 80; // default height
function my() {
console.log('pie created: ' + width + ' ' + 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;
};
my.render = function() {
my();
return my;
};
return my;
}
我可以通过链接方法调用这些函数,例如:
bar().width(200).render(); // bar created: 200 80
pie().height(300).render(); // pie created 720 300
在我的getter和setter方法相同的地方,是否可以编写这些代码? 例如,我计划在每个函数width()
函数完全相同。 如何使bar()
和pie()
函数继承共享的函数,例如width()
, height()
, render()
?
是的。关于这种特殊类型的实例化函数并停止使用其他方法的事情是,变量必须是实例化返回的函数( bar
或pie
)的函数范围的一部分。 由于这些变量是内部变量,无法在此范围之外访问,因此在扩展实例时无法找到它们。
在继续之前,请注意您的实现有些偏离。 首先,在console.log('bar created: ' + width + ' ' + height);
,从语义上讲是不正确的。 那实际上不是它的创建地,而是它的渲染地。 它是在调用bar()
时创建的。
然后,当您渲染此图表时,您应该做的是代替bar().width(200).render()
,例如
var barChart = bar().width(200);
d3.select('svg')
.append('g')
.call(barChart)
您不需要render()
。 相反, my()
的主体是您的渲染器。 但是,按照mbostocks的建议, my()
应该将d3选择作为参数,在此示例中将附加g
元素。 这是链接到的可重用图表教程的权利; 重新阅读它,您会明白我的意思。
最后,回答您的实际问题。 我的方法是使用d3.rebind
。 首先,您必须创建一个具有内部width
变量和width()
getter / setter的通用基类,如下所示:
function base() {
var width;
function my(selection) {
console.log('base: ' + width);
}
my.width = function(value) {
if (!arguments.length) return width;
width = value;
return my;
};
return my;
}
接下来,您要使bar
(和pie
)实质上扩展基数,如下所示:
function bar() {
var _base = base(); // instantiate _base, which has width() method
function my(selection) {
// In here, if you want to get width, you call `_base.width()`
// and, if there's some shared rendering functionality you want
// to put in base, you can run it with `selection.call(_base)`
}
d3.rebind(my, _base, 'width'); // make width() a function of my
return my;
}
最后一行,将width()
复制到my
以便您可以调用bar().width()
。 这是一个有效的小提琴。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.