3

这可能是一个非常基本的问题,因为我是新手。我正在从构造函数创建一个对象。我希望将对象的属性之一链接到变量。所以如果变量值改变,属性的值也应该改变。

示例:我正在研究 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
4

1 回答 1

5

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

ES5开始,可以通过(and ) 使用settergetter定义属性。ES5 的这一特性在现代浏览器中得到了相当广泛的支持,但较旧的浏览器(例如 IE8 和更早版本)没有。Object.definePropertyObject.defineProperties

使用吸气剂,可以做到这一点:

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变量的闭包(关于闭包的更多信息,请参见我的博客:闭包并不复杂。)

当然,这是否正常工作Kinetic.Rect将取决于如何Kinetic.Rect实现。

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

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

根据您对问题的评论:

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

上面的机制可以用来做到这一点,因为当然,你可以为你的所有 rect 设置 getter:

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

现在,所有 10 个矩形都将是可拖动的,或者不是,基于optvar.

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

于 2012-12-08T16:07:01.013 回答