peterS.: [Object].equals, [Object].dump, [Object].clone

Beitrag lesen

gruss Don P,

...
Das habe ich mir kurz angesehen. Sehr interessant, denn mich
interessieren vor allem scheinbar unlösbare Problemee : -).

...

Du schreibst dort:

...

Kannst du nochmal kurz schildern, wo genau das Problem liegt,
z.B. für ein "wasserdichtes [Object].clone"? Es gibt zwar viel
"Quälcode" (very funny) dort, aber wenig Doku, die erklären
würde, wozu die Kapriolen eigentlich gemacht werden.

mache ich - vorweg aber erstmal die erklaerungen fuer [equals] und [dump]:

wie schon vielfach erlaeutert, lassen sich JavaScript-objekte genau
dann nicht mehr verlaesslich miteinander vergleichen, sobald fuer
einen vergleich sowohl mit dem gleichheits- [==] als auch mit dem
identitaetsoperator [===] keine objektreferenzen mehr herangezogen
werden koennen.

in diesem fall muss man eine art "signatur" fuer jedes der beiden
objekte fuer den vergleich bemuehen.

diese im folgenden [dump] genannte methode, sollte sich in ihrer
grundfunktionalitaet an die von der mozilla.org implementierten
[toSource]-methode anlehnen, muss aber ueber diese hinaus auch der
tatsache rechnung tragen, dass objekte eben nicht allein durch
initilisierende konstruktor-aufrufe beschrieben werden koennen,
sondern immer auch hash-verhalten an den tag legen.

darueber hinaus erschwert die vermischung von JavaScript-api
(sprachkern) und DOM-api (dokument) das vergleichende geschaeft.

der [dump] beschreibt bzw. identifiziert elemente des DOM deswegen
in dieser reihenfolge anhand ihrer id-, tagName-, name-getter. noch
nicht ins DOM eingefuegte knoten-fragmente muessen ihr [innerHTML]
offenlegen.

fuer [clone] muss aehnlich vorgegangen werden, wenn man nicht der
Crockfordschen/Confordschen*[1] schule folgen will, in der das zu
kopierende object als prototyp eines anonymen und *leeren* konstruktors
referenziert wird - frei nachempfunden, aber prinzipiell so:

var object = (function (obj) {  
  
 var cnstr = new Function();  
 cnstr.prototype = obj;  
  
 return (new cnstr());  
});  
  
var arr = ["hallo", "welt"];  
var obj = object(arr);  
  
alert("arr : " + arr + "\nobj : " + obj + "\n(arr == obj) ? " + (arr == obj));  
alert("(arr.toString() === obj.toString()) ? " + (arr.toString() === obj.toString()));  
alert("(\"" + arr.join(" ") + "\" === \"" + obj.join(" ") + "\") ? " + (arr.join("! ") === obj.join("! ")));  
  
  
/*  
  bitte copy und paste nach [[link:http://jconsole.com/]]  
*/

*[1] - Douglas Crockford / Richard Conford

zurueck vom ausflug - weiter mit dem versuch moeglichst ideal zu klonen:

die [clone]-methode wird jedem build-in-typen - [Boolean], [Number], [String],
[Date], [Error], [RegExp], [Function] und schlussendlich allgemein [Object]
(was [Array] mit einschliesst) einzeln *verbacken* - warum?

im (rekursiven) clone-prozess verlaesst man sich zurecht darauf, dass das
weitgehend unbekannte objekt am besten ueber seine instanziierungs-geschichte,
seine prototypen-kette und erst zuletzt ueber seinen konstruktor *bescheid weiss*
und demzufolge die *richtige* clone methode in ebendieser reihenfolge automatisch
abgegriffen werden kann. dabei wird der erfolg einer instanziierung ueberwacht
und zuletzt gegebenenfalls auf den zu erwartenden konstruktor/typ zurueckgegriffen.

im nachfolgenden wiederum rekursiven aufbau der jeweils ersten objektebene
werden ausschliesslich nicht [prototype]-eigenschaften zugelassen. fuer diese
wird nach einer im sinne von JavaScript "nativen"*[2] [clone]-methode gesucht.
scheitert das projekt an dieser stelle kann das ergebnis einer vollstaendigen
iteration nicht mehr als *echter clone" bezeichnet werden, denn die nachfolgenden
fallbacks nehmen dann das was kommt - zuerst wird das nicht native [clone] probiert,
dannach wird nur noch referenziert.

*[2] siehe [this.isNative] aus [http://www.pseliger.de/jsExtendedApi/jsApi.Object.typeDetection.new.dev.js]:

this.isUndefined = function (obj) {  
  return (typeof obj == "undefined");  
};  
this.isNull = function (obj) {  
  return ((typeof obj == "object") && (!obj));  
};  
  
this.isValue = function (obj) {  
  return ((typeof obj == "string") || (typeof obj == "number") || (typeof obj == "boolean"));  
};  
this.isObject = function (obj) {  
  return (obj && (typeof obj == "object"));  
};  
  
this.isNative = function (obj) {  
  return (!isUndefined(obj) && !isNull(obj) && (typeof obj.constructor == "function"));  
};  
this.isAlien = function (obj) {  
  return (isObject(obj) && (typeof obj.constructor != "function"));  
};

so long - peterS. - pseliger@gmx.net

--
»Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:]