Could someone explain this to me?
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();
});
It seems to me that diagramImage
does not exist until the Kinetic constructor returns, but I am able (and seem to need to) assign context's strokeStyle
to diagramImage
's color -- before diagramImage
has been created? Why does this work?
EDIT: Full code:
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);
}
It will throw Reference error : x is not defined, when we assign a value to a variable without declaring it.
To create a variable in JavaScript, use the let keyword. To be concise, we can combine the variable declaration and assignment into a single line: let message = 'Hello! '; // define the variable and assign the value alert(message); // Hello!
If you assign a value to a variable that you have not declared with var , JavaScript implicitly declares that variable for you. Note, however, that implicitly declared variables are always created as global variables, even if they are used within the body of a function.
It means a variable must be declared with the data type that specifies the type of data a variable will store. JavaScript is a loosely typed language. It means it does not require a data type to be declared. You can assign any literal values to a variable, e.g., string, integer, float, boolean, etc.
Because where you are calling diagramImage.color
is within a closure / function that is passed in to the Kinetic.Shape
constructor. This function is not called / is not executed by the constructor until after the new instance created by the constructor is assigned to diagramImage
.
Here's a minimal example that may better explain what's happening:
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();
As Twisol noted, this can be improved by using this
instead. For example:
(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();
})();
However, as Chris noted, unless documented by the API - there is no guarantee that this
will refer to Kinetic.Shape
during the callback - so continuing to use diagramImage
here may still be the better of these 2 options.
In short, I think this is not the best API / example / use of JavaScript - and I would not consider this a nuance of JavaScript that you should have to deal with. Sure, these nuances are there if you need them - but you don't have to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With