当我向事件处理函数添加参数时,“this”会发生变化

时间:2013-08-22 08:36:11

标签: javascript kineticjs

我最近开始进入javascript,并且在理解方面遇到了一些障碍。以下可能是Kinetic.js特有的,我不确定。无论如何,最好用一个例子来说明。 http://jsfiddle.net/Y6Eww/1/

  var stage = new Kinetic.Stage({
    container: 'container',
    width: 578,
    height: 200
  });
  var layer = new Kinetic.Layer();

  var circle = new Kinetic.Circle({
    x: stage.getWidth() / 2,
    y: stage.getHeight() / 2 + 10,
    id: "TheCircle",
    radius: 70,
    fill: 'red',
    stroke: 'black',
    strokeWidth: 4,
    draggable: true
  });

  var dragendHandler = function dragendHandler() {
    console.log(this);
  };
  var dragstartHandlerParams = function dragstartHandlerParams(param1) {
    console.log(this+param1);
  };

  circle.on('click', function() {
    console.log(this);
  });
  circle.on('dragend', dragendHandler);
  circle.on('dragstart', dragstartHandlerParams("ROCK"));

  layer.add(circle);
  stage.add(layer);


  document.getElementById('removeClick').addEventListener('click', function() {
    circle.off('click');
    alert('onclick removed');
  }, false);

引用jsfiddle,我执行以下操作:

  1. 按“运行”按钮
  2. 拖动圆圈(触发dragstart和dragend)
  3. 点击圈子
  4. 这会产生以下控制台输出:

    [object Window]ROCK => Occurs after step 1.
    Uncaught TypeError: Cannot call method 'call' of undefined kinetic-v4.6.0.min.js:2 => Occurs after step 2.
    Kinetic.Circle {} => Occurs after step 2.
    Kinetic.Circle {} => Occurs after step 3.
    

    所以我的问题是:

    1. 为什么{j}最初运行时[object Window]ROCK会输出到控制台?没有发生dragstart,所以这不应该是原因。 dragstartHandlerParamsdragendHandler都是正在侦听拖动事件的函数表达式,因此我希望它们的行为相同(此时,似乎dragendHandler似乎没有被执行。 )
    2. 为什么this的上下文在dragstartHandlerParamsdragendHandler之间发生变化?
    3. 为什么dragstartHandlerParams不能作为处理程序工作?请注意,如果我在调用时省略参数,它确实有效。
    4. 如果对问题3的回答是“因为它需要一个事件参数”,那么如何将数据传递给事件处理程序?根据我的理解,Kinetic.js #on函数不会传递jQuery #on函数之类的数据。
    5. 提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

问题是,以下内容立即调用dragstartHandlerParams并将其return值(在本例中为undefined)传递给circle.on()

circle.on('dragstart', dragstartHandlerParams("ROCK"));

要在不调用函数的情况下指定参数,可以使用.bind()

circle.on('dragstart', dragstartHandlerParams.bind(circle, "ROCK"));

或者,您可以修改dragstartHandlerParams以返回新的function以传递给具有参数closed overcircle.on()

var dragstartHandlerParams = function dragstartHandlerParams(param1) {
  return function () {
    console.log(this+param1);
  };
};