问题
This may turn out to be a very basic question as I am a newbie. I am creating an object from a constructor. I want one of the properties of object to be linked to a variable. So if variable value changes, the property's value should also change.
Example: I am working on kineticjs and am creating an object from constructor Rect
. I want the value of the property draggable
to dynamically change to the value of optvar
whenever optvar
changes.
Var optvar="true";
rect = new Kinetic.Rect({
x: 22,
y: 7,
width: 0,
height: 0,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
draggable: optvar
});
optvar="false"; // I want value if rect.draggable to be equal to false
回答1:
This is not a basic question. :-)
As of ES5, it's possible to define properties with setters and getters via Object.defineProperty (and Object.defineProperties
). This feature of ES5 is quite broadly supported in modern browsers, but older browsers (such as IE8 and earlier) do not have it.
Using a getter, it's possible to do this:
var optvar=true;
rect = new Kinetic.Rect({
x: 22,
y: 7,
width: 0,
height: 0,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
Object.defineProperty(rect, "draggable", {
enumerable: true,
get: function() {
return optvar;
}
});
That creates a property on rect
that, when retrieved, returns the current value of optvar
. It works because the getter function is a closure over the optvar
variable (more about closures in my blog: Closures are not complicated.)
Of course, whether this works correctly with Kinetic.Rect
will depend on how Kinetic.Rect
is implemented.
The property created above is enumerable [shows up in for..in
loops like the others do], but is not writable. If you wanted it to be writable:
Object.defineProperty(rect, "draggable", {
enumerable: true,
get: function() {
return optvar;
},
writable: true,
set: function(value) {
optvar = value;
}
});
From your comment on the question:
I have multiple objects
rect
(all created dynamically). I want all objects' property to be linked to one variable.
The above mechanism can be used to do that, because of course, you can have getters for all of your rects:
var optvar = true;
var rect;
var rects = [];
while (rects.length < 10) {
rect = new Kinetic.Rect({
x: 22,
y: 7,
width: 0,
height: 0,
fill: 'red',
stroke: 'black',
strokeWidth: 4
});
Object.defineProperty(rect, "draggable", {
enumerable: true,
get: getDraggable
});
rects.push(rect);
}
function getDraggable() {
return optvar;
}
Now, all 10 of those rects will be draggable, or not, based on optvar
.
(Note: I'm assuming all of this code is in a function somewhere, so we're not creating global variables.)
来源:https://stackoverflow.com/questions/13779134/object-property-to-dynamically-change-with-the-value-of-assigned-variable