有人可以向我解释吗?

var diagramImage = new Kinetic.Shape(function () {
    var context = this.getContext();
    context.beginPath();
    context.lineWidth = 1;
    //This is crazy tricks. It's part of the KineticJS demo website, but how am I able to assign diagramImage.color here?
    context.strokeStyle = diagramImage.color;

    var lastVertice = polygon.Vertices[polygon.Vertices.length - 1];

    context.moveTo(lastVertice.X, lastVertice.Y);

    for (var i = 0; i < polygon.Vertices.length; i++) {
        var vertice = polygon.Vertices[i];
        context.lineTo(vertice.X, vertice.Y);
    }

    context.stroke();
    context.closePath();
});

在我看来,直到Kinetic构造函数返回之前,diagramImage才存在,但是我可以(而且似乎需要)在创建strokeStyle之前将上下文的diagramImage分配给diagramImage的颜色。为什么这样做?

编辑:完整代码:
function DrawPolygon(diagramLayer, polygon) {
    var diagramImage = new Kinetic.Shape(function () {
        var context = this.getContext();
        context.beginPath();
        context.lineWidth = 2;
        //This is crazy tricks. It's part of the KineticJS demo website, but how am I able to assign diagramImage.color here?
        context.strokeStyle = diagramImage.color;

        var lastVertice = polygon.Vertices[polygon.Vertices.length - 1];

        context.moveTo(lastVertice.X, lastVertice.Y);

        for (var i = 0; i < polygon.Vertices.length; i++) {
            var vertice = polygon.Vertices[i];
            context.lineTo(vertice.X, vertice.Y);
        }

        context.stroke();
        context.closePath();
    });

    diagramImage.color = "red";

    diagramImage.on("mouseover", function () {
        this.color = "green";
        diagramLayer.draw();
    });

    diagramImage.on("mouseout", function () {
        this.color = "red";
        diagramLayer.draw();
    });

    diagramLayer.add(diagramImage);
    planViewStage.add(diagramLayer);
}

最佳答案

因为调用diagramImage.color的位置在传递给Kinetic.Shape构造函数的闭包/函数内。直到构造函数创建的新实例分配给diagramImage后,构造函数才调用此函数/不会执行此函数。

这是一个最小的示例,可以更好地解释正在发生的事情:

var MyObject = function(f){
  this.myFunc = f; // f is executed sometime later...
};
MyObject.prototype.execute = function(){
  this.myFunc();
};

var myObjInst = new MyObject(function(){
  console.log("myObjInst:", myObjInst);
});
myObjInst.execute();

正如Twisol所指出的,这可以通过使用this来改善。例如:
(function(){
  var MyObject = function(f){
    this.myFunc = f; // f is executed sometime later...
  };
  MyObject.prototype.execute = function(){
    this.myFunc();
  };

  var myObjInst = new MyObject(function(){
    console.log("myObjInst:", this);
  });
  myObjInst.execute();
})();

但是,正如Chris所指出的那样,除非API进行了说明,否则-无法保证this在回调期间将引用Kinetic.Shape-因此,在此处继续使用diagramImage可能仍然是这两个选项中更好的选择。

简而言之,我认为这不是最佳的API/示例/JavaScript的使用-并且我不认为这是您应该处理的JavaScript的细微差别。当然,如果您需要这些细微差别,就可以在那里-但您不必这样做。

09-07 15:25