object property to dynamically change with the value of assigned variable

白昼怎懂夜的黑 提交于 2021-02-07 09:11:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!