如果我将d3.scale函数分配给变量,我可以传入一个数字,它会正确地缩放该数字。
但是,如果我在对象中包装相同的函数,它不会返回我期望的答案。为什么呢?
var applyScale1 = d3.scale.ordinal()
.domain([0, 2])
.rangePoints([0, 1024]);
console.log(typeof(applyScale1)); // "function"
console.log(applyScale1(1)); // 0
console.log(applyScale1(5000)); // 1024 *Correct*
// But wrapping that in an object doesn't work. Why?
var obj = {
returnResult: function(n) {
var fn = d3.scale.ordinal()
.domain([0, 2])
.rangePoints([0, 1024]);
return fn(n);
},
returnFunction: function() {
return d3.scale.ordinal()
.domain([0, 2])
.rangePoints([0, 1024]);
},
withCall: function(n) {
var fn = d3.scale.ordinal()
.domain([0, 2])
.rangePoints([0, 1024]);
var nScaled = fn.call(n);
return nScaled;
},
applySelf: function(n) {
var self = this;
var fn = d3.scale.ordinal()
.domain([0, 2])
.rangePoints([0, 1024]);
var nScaled = fn.apply(self, [n]);
return nScaled;
},
usingCall: function(n) {
return d3.scale.ordinal()
.domain([0, 2])
.rangePoints([0, 1024])
.call(n);
},
};
console.log(obj.returnResult(1)); // = 0
console.log(obj.returnResult(5000)); // = 0 * Wrong *
console.log(obj.returnFunction()(1)); // = 0
console.log(obj.returnFunction()(5000)); // = 0 * Wrong *
console.log(obj.withCall(1)); // = 0
console.log(obj.withCall(5000)); // = 0 * Wrong *
console.log(obj.applySelf(1)); // = 0
console.log(obj.applySelf(5000)); // = 0 * Wrong *
console.log(obj.usingCall(1)); // = 0
console.log(obj.usingCall(5000)); // = 0 * Wrong *
答案 0 :(得分:1)
您正在使用序数比例,这是具有离散域的比例。在您的情况下,该离散域是集合{0,2}。我不确定如果你输入的数字不在那个集合1024中,行为是如何定义的,但我相信d3会留下这个未定义的行为。
如果传入0或2,结果将如预期一样。
本声明还有另一个问题:
return d3.scale.ordinal()
.domain([0, 2])
.rangePoints([0, 1024])
.call(n);
要调用的第一个参数是'thisArg':https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
该块应为:
return d3.scale.ordinal()
.domain([0, 2])
.rangePoints([0, 1024])
.call(null, n);
答案 1 :(得分:0)
很明显,d3返回的函数在调用时保持某种状态。但是,每次在分配到obj
由于没有维持状态,因此无法计算出合适的结果。
如果您尝试直接调用函数实例,这可能是更好的方法:
var obj = {
returnResult: d3.scale.ordinal()
.domain([0, 2])
.rangePoints([0, 1024])
}
这将允许您在不重新创建对象的情况下立即执行您正在执行的操作。