0

If '_position' is a Point object member of Sprite, with Number members x and y, and its own get/set definitions, how can I apply a higher level 'set' so this will work (EDIT: I would like to reach the 'set' function in Sprite, rather than the 'set' function in Point):

// EDIT: example calling line, embedding context should be unimportant
// 'this' is a Sprite instance
this.position.set(x, y);


Object.defineProperties(Sprite.prototype, {

// a bunch of other properties excised here

    position: {
        get: function() {
            return this._position;
        },

        set: function(_pos) {
            this._position.x = this.transform.x = _pos.x;
            this._position.y = this.transform.y = _pos.y;
            this.transform.updateTransform();
        }
    }
};

What happens currently is that "this.position" goes to the "position.get" property, and then "this.position.set" goes through to the Point set function. It seems like attempts to 'set' any object with it's own get/set will drop down to the lowest level.

It feels like there must be a way to change this behaviour, but my google and stackoverflow searches are not coming up with an answer. It's likely there's a proper term for what I want to do here, without which I'm struggling the phrase the question correctly.

For instance: this is close, but doesn't quite work in my situation

EDIT: I don't control the source file for Point, or the function where the this.position.set(x,y); is held. Although I may be able to get permission for a change to the calling syntax if I can prove that it won't break the other objects which actually want to use the Point set function.

4

2 回答 2

1

由于Bergi没有发布答案,我会的,因为这是一个好问题。

如果您不控制任何周围的代码,那么不幸的是,只有丑陋的方法可以做到这一点。

A)如Bergi建议的那样,返回一个可以做任何你想做的事情的代理对象。

缺点是周围的代码可能期望它发送的对象与接收的对象匹配。开发人员会比较对象引用而不是值,这并非不可想象,然后这样的比较就会失败。但这已经在您的代码中发生了,所以如果您已经在使用它并且没有任何问题,那么您就可以开始了。

另外,如果你这样做,你应该做MyPoint.prototype = new Point()一些事情,以便如果将新方法添加到 Point,它们也将在你的类中可用。

B)为构造函数中的每个对象或您设置它的任何位置手动覆盖this._position.set和/或设置器和获取器。这很慢而且非常肮脏,这个想法太糟糕了,我写了一个片段然后删除了它:)

这里有一些关于你应该做什么的选项。

A) 同意Sprite使用sprite.position = newPos或的用户sprite.setPosition(newPos)。然后你应该在 getter 中返回一个Object.freeze()d 副本,_position以确保它没有被不当使用。

B)同意作者Point在它改变时发出一些事件,然后可以被监听Sprite

于 2015-11-05T03:10:27.697 回答
0

你不明白Object.defineProperties。不要难过,在我进一步研究之前我也没有。您set将 Object 的单个属性的方法与调用的属性混淆了,该属性set实际上可能拥有自己的 set 方法。value如果你愿意,你可以在你的属性中创建一个方法。我猜这是你需要看到的:

Object.defineProperties(Sprite.prototype, {
  set: {
    // can also have get and set here
    value: function(){
      // inside Sprite.prototype.set
    }
  },
  position: {
    get: function() {
      return this._position;
    },
    set: function(_pos) {
      this._position.x = this.transform.x = _pos.x;
      this._position.y = this.transform.y = _pos.y;
      this.transform.updateTransform();
    }
  }
});

我觉得这很酷。这种东西肯定是在幕后使用的,所以length属性确实是方法。

于 2015-11-05T01:20:01.527 回答