object属性,使用赋值变量的值动态更改

时间:2012-12-08 15:59:05

标签: javascript kineticjs javascript-objects

由于我是新手,这可能会成为一个非常基本的问题。我正在从构造函数创建一个对象。我希望将对象的一个​​属性链接到一个变量。因此,如果变量值发生变化,则属性的值也应该更改。

示例:我正在研究kineticjs并且正在从构造函数Rect创建一个对象。我希望只要draggable更改,属性optvar的值就会动态更改为optvar的值。

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 个答案:

答案 0 :(得分:5)

这不是一个基本问题。 : - )

ES5开始,可以通过Object.defineProperty(和Object.defineProperties)使用 setters getters 定义属性。现代浏览器广泛支持ES5的这一功能,但旧版浏览器(如IE8及更早版本)没有它。

使用getter,可以这样做:

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;
    }
});

这会在rect上创建一个属性,在检索时会返回optvar的当前值。它起作用,因为getter函数是对optvar变量的闭包(更多关于我博客中的闭包:Closures are not complicated。)

当然,这与Kinetic.Rect是否正常有效取决于Kinetic.Rect的实施方式。

上面创建的属性是可枚举的[显示在for..in循环中,就像其他人一样),但是不可写。如果你想让它可写:

Object.defineProperty(rect, "draggable", {
    enumerable: true,
    get:        function() {
        return optvar;
    },
    writable:   true,
    set:        function(value) {
        optvar = value;
    }
});

从您对该问题的评论:

  

我有多个对象rect(全部动态创建)。我希望所有对象的属性都链接到一个变量。

上述机制可以用来做到这一点,因为当然,你可以拥有所有你的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;
}

现在,根据optvar,所有10个rects都可以拖放。

(注意:我假设所有这些代码都在某个函数中,因此我们不会创建全局变量。)