私は、いくつかの奇妙なことを可能にするかなり醜いライブラリに取り組んでいます。グラフを使用すると、チェーンのようなスタイルで一連のコレクションをマップでき、システム全体で値を変更するときに変更できます。
終了タイプが JS プリミティブである場合に問題が発生しました。
私の場合、値とオブジェクトを使用してグラフを作成した後、次のようなことができます。
CHAIN.components[0].value = 20;
components
セッターとゲッターを使用したグラフのノードに対するフィルター関数です。コンポーネントでフィルタリングされたノードが 1 つしかない場合、ユーザーが設定したデフォルト値は、これを行わなくても使用できます。CHAIN.components.value = 20; しかし、むしろこれ: CHAIN.components = 20;
ここでの問題は、ノードがデフォルト以外の他のメソッドまたはプロパティを持つ可能性があることです(私の場合は on に設定されています) value
。
Number.prototype をハッキングせずに Number オブジェクトでセッターとゲッターを使用するCHAIN.components
方法これは問題です。セットを作成するたびCHAIN.components.func()
に Number.prototype に追加してから削除する必要があるからです。func
components
この種の行動を達成するための別のアイデアはありますか?
あなたはコードが欲しかったので、ここにあります:
/*jslint nomen: true, sloppy: true*/
GRID.modules.OHM || Object.extend(GRID.modules, ( function() {
var Node, Nodes, Ohm, num_proto = Number.prototype.__clone(), str_proto = String.prototype.__clone();
Node = function(uid) {
var UID = uid;
this.getUID = function() {
return UID;
};
};
Nodes = function() {
var stack = [];
this.add = function(id, val) {
var n = new Node(stack.length);
val.id = id;
Object.extend(n, val);
stack.push(n);
return n.getUID();
};
this.getById = function(id) {
return stack.filter(function(v) {
var a = id || v.id;
return (v.id === a);
});
};
this.getByUID = function(UID) {
return stack[UID];
};
this.get = function(callback) {
!Object.isString(callback) || ( callback = [callback]);
var f = Object.isFunction(callback) ? callback : (Object.isArray(callback) ? function(k) {
return (callback.indexOf(k.id) >= 0);
} : function(k) {
return true;
});
return stack.filter(f);
};
};
Ohm = function(n) {
var graph = n || (new Nodes()), filters = {}, __nodes = {}, addGS = function(obj, name, conf, binder) {
var alfa = {};
Object.extend(alfa, conf);
if (!alfa.get) {
alfa.get = function() {
var a = this.g.getById(this.p);
return a.length === 1 ? a[0] : a;
}.bind(binder);
} else {
alfa.get = alfa.get.bind(binder);
}
if (!alfa.set) {
alfa.set = function(value) {
this.g.getById(this.p).forEach(function(k) {
Object.extend(k, value);
return true;
});
}.bind(binder);
} else {
alfa.set = alfa.set.bind(binder);
}
Object.defineProperty(obj, name, alfa);
}, add = function(id, node) {
if (__nodes.hasOwnProperty(id)) {
addGS(__nodes, id, {
enumerable : true
}, {
t : this,
p : id,
g : graph
});
}
return graph.add(id, node || {});
};
Object.extend(this, {
add : function() {
add.apply(this, arguments);
},
map : function(name, f, that) {
var n = name, filterer = ['add', 'map', '__all'];
n = Object.isFunction(n) ? name.apply(that, arguments.slice(3)) : n;
if (filterer.indexOf(n.toLowerCase()) >= 0) {
console.log("You can't map over a basic property of object !!! Please read the freakin' manual.");
return null;
}
if (!filters.hasOwnProperty(n)) {
filters[n] = new Ohm(graph);
addGS(this, n, {
get : function() {
this.g.get(this.f).forEach(function(v, key, arr) {
var temp, binder;
if (arr.length !== 1) {
if (!this.filt.hasOwnProperty(v.id)) {
addGS(this.filt, v.id, {
set : function(value) {
this.t.g.getById(this.p).filter(this.t.f).forEach(function(k) {
Object.extend(k, value);
});
},
get : function() {
var a = this.t.g.getById(this.p).filter(this.t.f);
return a.length === 1 ? a[0] : a;
}
}, {
t : this,
p : v.id
});
(key !== arr.length - 1) || Object.extend(this.filt, this.g.get(this.f));
}
} else {
if (Object.isFunction(v.__new__)) {
v.__default = function() {
return Object.extend((new this.__new__(arguments)), this);
};
}
if (!Object.isUndefined(v.__default)) {
temp = this.filt;
this.filt = Object.isFunction(v.__default) ? v.__default.bind(v) : v.__default;
if (Object.isNumber(this.filt) || Object.isString(this.filt)) {
var prot = Object.isNumber(this.filt) ? Number : String;
for (var i in temp) {
if (temp.hasOwnProperty(i) && !prot.prototype.hasOwnProperty(i)) {
var bin = {
t : temp,
m : i,
p : prot,
};
Object.defineProperty(prot.prototype, i, {
set : function(value) {
Object.defineProperty(this.p.prototype, this.m, {
configurable : true, // defaults to false
writable : false,
value : 1
});
delete this.p.prototype[this.m];
this.t[this.m] = value;
}.bind(bin),
get : function() {
Object.defineProperty(this.p.prototype, this.m, {
configurable : true, // defaults to false
writable : false,
value : 1
});
delete this.p.prototype[this.m];
return this.t[this.m];
}.bind(bin),
enumerable : true,
configurable : true
});
}
}
} else {
Object.extend(this.filt, temp);
}
}
if (Object.isNumber(this.filt) || Object.isString(this.filt)) {
var prot = Object.isNumber(this.filt) ? Number : String;
for (var i in v) {
if (v.hasOwnProperty(i) && !prot.prototype.hasOwnProperty(i)) {
var bin = {
t : v,
m : i,
p : prot,
};
Object.defineProperty(prot.prototype, i, {
set : function(value) {
Object.defineProperty(this.p.prototype, this.m, {
configurable : true, // defaults to false
writable : false,
value : 1
});
delete this.p.prototype[this.m];
this.t[this.m] = value;
}.bind(bin),
get : function() {
Object.defineProperty(this.p.prototype, this.m, {
configurable : true, // defaults to false
writable : false,
value : 1
});
delete this.p.prototype[this.m];
return this.t[this.m];
}.bind(bin),
enumerable : true,
configurable : true
});
}
}
} else {
Object.extend(this.filt, v);
}
}
}, this);
return this.filt;
},
set : function(value) {
this.g.get(this.f).forEach(function(k) {
Object.extend(k, value);
});
}
}, {
t : this,
f : f,
g : graph,
filt : filters[n]
});
}
}
}, true, true);
addGS(this, '__all', {
get : function() {
var a = this.g.getById();
Object.extend(__nodes, a.length === 1 ? a[0] : a);
return __nodes;
},
enumerable : true
}, {
t : this,
p : null,
g : graph
});
};
window['Ω'] = Ohm;
return {
OHM : Ohm,
};
}()));
そして今デモ:
var c = new Ω();
c.add('ann', {
__default : 58,
blah : 98,
ceva : function()
{
console.log('asd');
}
});
c.add('ann2',{
__default: function(){
console.log('hello');
},
abc: 78,
dce: function(){
console.log(' world');
}
};
c.add('b2', {
__new__ : function() {
this.init = function() {
this.id = 86;
};
this.mer = function() {
console.log(this);
};
},
els : 'asadar'
});
c.map('b2', function(k) {
return k.id === 'b2';
});
c.map('ann', function(k) {
return k.id === 'ann';
});
c.map('ann2', function(k) {
return k.id === 'ann2';
});
console.log(c.ann); // returns 58 ( the __default value )
console.log(c.ann.blah); // returns 98
console.log(c.ann.blah.blah); // undefined
console.log(c.ann2); // function()
c.ann2(); // prints out 'hello'
c.ann2.cde(); // prints out 'world'
c.ann2 = 60;
console.log(c.ann2); // 60
console.log(c.ann2.cde()); // prints out 'world'
このコードは機能しますが、Number または String プロトタイプを使用しなければならない部分が気になります。これを行う別の方法はありますか?
その理由は、PHP では実行できるが JS では実行できないと誰かが言ったことを実行するためです。この男は最近、私と一緒に WebGL シェーダーで作業していて、複数の効果を FBO と組み合わせて使用するために 700 行のコードを書かなければならないことを嫌っていました。 PHPで書かれたこのような同様のツールで彼を連れて行った100。はい、私はプリミティブ プロトタイプのアクセサーがハックであることを知っていますが、チェーン エンド オブジェクトがプリミティブである場合、valueOf を使用せずにどうすればそれを変更できますか?