2015-11-03 58 views
0

如果'_position'是Sprite的Point对象成员,其Number成员x和y以及它自己的get/set定义,我如何应用更高级别的'set'以便它能工作(编辑:我想到达“设置”功能雪碧,而不是点“设置”功能):如何在属性类型有自己的'set'时使用对象属性上的'set'?

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

目前发生什么是“this.position”转移到“position.get”属性,然后“ this.position.set“进入点设置功能。似乎试图用它自己的get/set来设置任何对象将会降到最低级别。

感觉就像一定有办法改变这种行为,但我的谷歌和stackoverflow搜索没有拿出一个答案。这很可能是我想要在这里完成的一个适当的术语,没有这个术语,我正在努力纠正这个问题。

例如: this接近,但确实在我的情况不太工作

编辑:(我不控制点源文件或功能,其中this.position.set X ,Y);举行。虽然我可以获得更改调用语法的权限,但我可以证明它不会打破实际上想要使用Point set函数的其他对象。

+0

第一次海报然后可以听上......请让我知道如果我错过了什么或措辞的质疑不佳。 – PeteB

+0

你的意思是做'this.position = {x:x,y:y};'?除非你指定给财产,否则你的执行者不会被执行。 – Bergi

+0

我们看不到你的'Sprite'构造函数。它里面的所有代码都是?糟糕的编码习惯。 'Object.hasOwnProperty(propString)'将测试属性是否属于特定对象。 – PHPglue

回答

1

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

如果你不控制任何周围的代码,那么不幸的是,只有丑陋的方法才能做到这一点。按照Bergi的建议,返回一个代理对象,它可以做任何你想做的事情。

缺点是周围的代码可能期望它发送的对象与接收到的对象相匹配。开发人员会比较对象引用而不是值,这并不是不可思议的,然后这样的比较就会失败。但是那会在你的代码中发生,所以如果你已经使用它并且没有任何东西被破坏,那么你很好。另外,如果你这样做,你应该制作MyPoint.prototype = new Point()或其他东西,这样如果新的方法被添加到Point中,它们也将在你的课堂上使用。

B)重写this._position.set和/或setter和getters为构造函数中的每个对象或您设置的任何位置手动设置。这是缓慢和非常肮脏,是一个想法如此糟糕,我写了一个片段,然后删除它:)

这里有一些选项,你应该实际上做什么。

A)同意用户Sprite使用sprite.position = newPossprite.setPosition(newPos)。那么你应该在吸气剂中返回一个Object.freeze() d _position的副本,以确保它没有被不恰当地使用。

B)与Point笔者同意发出一些事件,当它改变由这里Sprite

+0

接受为答案,因为这是最全面的答复。现在我已经使用了自定义对象的丑陋解决方案,而我尝试进一步修改该行的更改。我没有考虑过比较参考的可能性,感谢你的警告! – PeteB

0

你不明白Object.defineProperties。不要觉得不舒服,直到我进一步研究它,我也没有感觉不好。你是混淆了一个名为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属性真的是方法。

+0

我不知道为什么这个答案被标记下来,它似乎是一种解决方案的有效方法。我相信例子的语法可能有点怪异,例如使用“值”作为集合内的属性。 – PeteB