"这个“;当我向事件处理程序函数添加参数时会发生更改

"this" changes when I add parameters to event handler function

本文关键字:参数 添加 函数 程序 这个 quot 事件处理      更新时间:2023-09-26

我最近开始学习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. 按下Run(运行)按钮
  2. 拖动圆(触发拖动开始和拖动结束)
  3. 单击圆

这将导致以下控制台输出:

[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. 当jsfiddle最初运行时,为什么[object Window]ROCK会向控制台输出?拖动启动没有发生,所以这不应该是原因。dragstartHandlerParamsdragendHandler都是监听拖动事件的函数表达式,所以我希望它们的行为相同(在这一点上,似乎没有执行dragendHandler
  2. 为什么this的上下文在dragstartHandlerParamsdragendHandler之间发生变化
  3. 为什么dragstartHandlerParams不能作为处理程序工作?请注意,如果我在调用时省略参数,它确实有效
  4. 如果问题3的答案是"因为它需要一个事件参数",我该如何将数据传递给事件处理程序?据我所知,Kinetic.js #on函数不像jQuery #on函数那样传递数据

提前感谢您的帮助。

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

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

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

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

或者,您可以修改dragstartHandlerParams以返回一个新的function,将其传递给已关闭参数的circle.on()

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