我似乎在使用变量在Javascript中完全创建之前使用它,但这有效 - 为什么?

Sea*_*son 5 javascript jquery kineticjs

有人可以向我解释一下吗?

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();
});
Run Code Online (Sandbox Code Playgroud)

在我看来,diagramImage在Kinetic构造函数返回之前不存在,但我能够(并且似乎需要)在创建之前将上下文指定strokeStylediagramImage颜色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);
}
Run Code Online (Sandbox Code Playgroud)

zie*_*mer 8

因为您调用的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();
Run Code Online (Sandbox Code Playgroud)

正如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();
})();
Run Code Online (Sandbox Code Playgroud)

但是,正如Chris指出的那样,除非API记录在案 - 否则无法保证在回调期间this会引用Kinetic.Shape- 所以继续在diagramImage这里使用可能仍然是这两个选项中更好的选择.

简而言之,我认为这不是JavaScript的最佳API /示例/使用 - 我不认为这是您应该处理的JavaScript的细微差别.当然,如果你需要它们,这些细微差别就在那里 - 但你没有必要.