Javascript 如何在d3.js中的函数之间共享作用域?

Javascript 如何在d3.js中的函数之间共享作用域?,javascript,d3.js,Javascript,D3.js,我不确定这是d3.js问题还是javascript可见性问题。我有两个函数将同一事件侦听器分配给不同的节点: function render_line(){ var x = d3.scale.ordinal(); ... d3.select("#my_line").on("click", onclick); } function render_bar(){ var y= d3.scale.linear(); ... d3.select("#m

我不确定这是d3.js问题还是javascript可见性问题。我有两个函数将同一事件侦听器分配给不同的节点:

function render_line(){
    var x = d3.scale.ordinal();
    ...

    d3.select("#my_line").on("click", onclick);
}

function render_bar(){
    var y= d3.scale.linear();
    ...

    d3.select("#my_bar").on("click", onclick);
}

function onclick(d,i){
    use(x,y) // error: can't access x or y
    ...
}

我认为
render_line()
render_bar()
共享同一个事件侦听器函数是有意义的,因为单击其中一个函数也应该更新另一个函数,但我不知道如何解决变量范围问题。

如果您在函数之外声明变量,然后分配给它们(不在函数中使用
var
关键字)那么您的函数将被授予从这些变量中设置和获取值的权限

var x,y;
function foo(){
  x = d3.scale.ordinal();
  d3.select("...").on("click",onclick);
}
function bar(){
  y = d3.scale.linear();
  d3.select("...").on("click",onclick);
}
function onclick(){
  // has access to both x and y here
}
或者,如果感觉太脏,则在事件注册期间围绕局部变量创建一个闭包,将值传递给共享函数:

function foo(){
  var x = d3.scale.ordinal();
  d3.select("...").on("click",function(evt){
    onclick.call(this,evt,x);
  });
}
function foo(){
  var y = d3.scale.linear();
  d3.select("...").on("click",function(evt){
    onclick.call(this,evt,y);
  });
}
function onclick(evt,scale){
  // Use 'scale' passed in
}

请注意,在这种情况下,您不能稍后取消注册
onclick
,因为该函数不是向处理程序注册的函数。

如果您在函数外部声明变量,然后分配给它们(在函数中不使用
var
关键字)然后,您的函数将被授予从这些变量中设置和获取值的权限

var x,y;
function foo(){
  x = d3.scale.ordinal();
  d3.select("...").on("click",onclick);
}
function bar(){
  y = d3.scale.linear();
  d3.select("...").on("click",onclick);
}
function onclick(){
  // has access to both x and y here
}
或者,如果感觉太脏,则在事件注册期间围绕局部变量创建一个闭包,将值传递给共享函数:

function foo(){
  var x = d3.scale.ordinal();
  d3.select("...").on("click",function(evt){
    onclick.call(this,evt,x);
  });
}
function foo(){
  var y = d3.scale.linear();
  d3.select("...").on("click",function(evt){
    onclick.call(this,evt,y);
  });
}
function onclick(evt,scale){
  // Use 'scale' passed in
}

请注意,在这种情况下,您不能稍后取消注册
onclick
,因为这不是向处理程序注册的函数。

onclick
处理程序真的需要同时访问x和y,还是只想访问其中一个?除了x和y之外,还有其他变量,比如占位符对于2个svg标记(一个用于行,另一个用于条),
onclick
处理程序是否真的需要同时访问x和y,还是只想访问其中一个?除了x和y之外,还有其他变量,如2个svg标记的占位符(一个用于行,另一个用于条)我喜欢。我不知道申请。谢谢。我喜欢。我不知道申请。谢谢