Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将D3函数包装在对象中不会';不行。为什么?_Javascript_D3.js - Fatal编程技术网

Javascript 将D3函数包装在对象中不会';不行。为什么?

Javascript 将D3函数包装在对象中不会';不行。为什么?,javascript,d3.js,Javascript,D3.js,如果我给一个变量分配一个d3.scale函数,我可以传入一个数字,它会正确地缩放这个数字 但是,如果我将同一个函数包装到一个对象中,它不会返回我期望的答案。为什么? var applyScale1 = d3.scale.ordinal() .domain([0, 2]) .rangePoints([0, 1024]); console.log(typeof(applyScale1)); // "function" console.log(applyScale1(1));

如果我给一个变量分配一个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 *

很明显,d3返回的函数在调用时保持某种状态。但是,当分配给
obj

由于未维护任何状态,因此无法计算适当的结果

如果您试图直接调用函数实例,这可能是一种更好的方法:

var obj = {
   returnResult: d3.scale.ordinal()
      .domain([0, 2])
      .rangePoints([0, 1024])
}

这将允许您执行现在正在执行的操作,而无需每次重新创建对象。

您使用的是有序比例,即具有离散域的比例。在您的例子中,这个离散域就是集合{0,2}。我不确定如果你输入一个不在1024集中的数字,行为会如何定义,但我相信d3没有定义这个

如果传入0或2,结果将与预期一致

本声明中还有一个问题:

return d3.scale.ordinal()
  .domain([0, 2])
  .rangePoints([0, 1024])
  .call(n);
要调用的第一个参数是“thisArg”:

该块应改为:

return d3.scale.ordinal()
  .domain([0, 2])
  .rangePoints([0, 1024])
  .call(null, n);

这里有一个难题:

在JSFIDLE中找到的代码就是适合我的答案。谢谢你,卡尔!最后的工作解决方案是:
var obj={myScale:function(n){return d3.scale.ordinal().domain([0,2])。rangePoints([0,1024])。call(null,n);}}}console.log(obj.myScale(0));/返回0 console.log(obj.myScale(2));//返回1024个
感谢您的帮助@cesutherland在这里提出了一个适合我需要的解决方案: