これprototype
は、残念ながら持っていないオブジェクトインスタンス専用です。このようなコンストラクターがある場合:
function Color(r,g,b,a){
for (var i=0; i<4; i++)
this[i] = arguments[i];
}
それはで動作します
Object.defineProperty(Color.prototype, "r", {
get: function() { return this[0]; } // setter analogous
};
ただし、これらのColor
インスタンスはアレイではありません。それらにlength
プロパティを与えてから継承させることもできますArray.prototype
が、実際には配列ではありません。@Troutsソリューションはそのようなものですが、色は実際には配列ではないため(5番目の値をプッシュすることはできません)、問題ないと思います。
color
別の方法は、ゲッターから返す配列をこれらのプロパティで拡張することでした。誰かが値にアクセスするたびにそれを行うことができますが(現在のように、ゲッターで新しい配列を作成します)、変更を伝播して同じインスタンスを返すことをお勧めします。現在のプロパティ定義は「setColor」や「getCurrentColor」のようなものです。
したがって、実際には2つの別個のものが必要です。Color
値ごとに複数のプロパティを持つオブジェクト(つまり、 0
== r
)。color
配列を受け入れ、それぞれのオブジェクトに単一の値を設定するグローバル変数のセッター。
// version with private values
function Color(r, g, b, a) {
// r, g, b and a are private-scoped variables
var desc = {
"0": {
get:function(){return r;},
set:function(val){ if(+val<256&&val>=0) r=+val;}
},
…
}
// use those property descriptors multiple times
desc.r = desc[0];
…
Object.defineProperties(this, desc);
}
// or version with public and unlimited read/write access to the properties:
function Color(r,g,b,a){
for (var i=0; i<4; i++)
this[i] = arguments[i];
}
Object.defineProperties(Color.prototype, {
r: { get:function(){return this[0];}, set:function(r){this[0]=r;} },
…
}
// and for both versions we can add array-like methods on the prototype
var cprot = Color.prototype, aprot = Array.prototype;
Object.defineProperty(cprot, "length", {value:4});
// we only need accessor functions here, nothing which changes the array [length]
cprot.map = aprot.map;
cprot.reduce = aprot.reduce;
cprot.slice = aprot.slice;
cprot.join = aprot.join;
// you might want to add other utilities like
cprot.toString = function() {
return "rgba("+this.join(",")+")"; // using array method from above
};
cprot.getHex = function() {
function hex(n) { return (n<16?"0":"") + n.toString(16); }
return "#"+this.slice(0, 3).map(hex).join("");
};
そして、あなたの色の値の設定者:
function defineColorProperty(obj, prop, color) {
// again, color is private-scoped
if (!color || !(color instanceof Color)) color = new Color(0, 0, 0, 0);
Object.defineProperty(obj, prop, {
get: function(){ return color; }, // a cool Color instance!
set: function(val) {
if (Object(val)!==val) return; // accept objects (including arrays)
for (var i=0; i<4 && i<val.length; i++)
color[i] = val[i];
},
enumberable: true
});
return color;
}
// usage:
> defineColorProperty(window, "color");
Object[Color]: 0, 0, 0, 0
> color = [255, 0, 120, 1];
> color.r = 42;
> color[0]
42
> color = [0, 0];
> ""+color
"rgba(0,0,120,1)"
> var x = color;
> x.b = 255;
> x.getHex()
"#0000FF"