简体   繁体   中英

object property to dynamically change with the value of assigned variable

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

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.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM