• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Parameter als JSON String

Status
Für weitere Antworten geschlossen.

Gilles

Blogger
Hey Leute. Ich hätte da mal eine Frage bezüglich Parametern
und eval.

Folgende Situation:

ich habe folgenden Code

PHP:
var MyObject = function(arguments) {

  var myElement;
  var myText;

  var __construct = function(args) {
    for( var arg in args) {                     
        eval(arg+" = "+args[arg]+";");
     }

  };

  // Auslesen des Elementes
  var getMyElement = function() {
    return MyElement;
  };

__construct(arguments);
};

var meinObjekt = new MyObject({myElement: document.getElementById('test'), myText : "Test123"});

alert(meinObjekt.getMyElement());

Das er meckern würde bei text ist mir klar. Da muss ich wohl 2 verschiedene evals machen. Für Objekte und Strings. Aber selbst wenn ich nur das Element setze mag er mir das nicht ausgeben. Kennt sich da einer mit eval aus? Oder kennt eine andere Möglichkeit, wie ich leicht Attribute setzen kann mit einer Schleife.

Vielen dank schonmal für Tipps :)
 
Ich hätte es wohl wie folgt gemacht, aber in OOP in JavaScript bin ich nicht so erfahren.

Code:
var MyObject = function (arguments)
{
    this._myElement = (arguments.myElement) ? (arguments.myElement) : null;
    this._myText    = (arguments.myText) ? (arguments.myText) : "default";

    // Auslesen des Elementes
    this.getMyElement = function ()
    {
        return this._myElement;
    };
};

var meinObjekt = new MyObject({myElement : document.getElementById('test'),
                               myText    : "Test123"});

alert(meinObjekt.getMyElement());

eval() ist jedenfalls keine gute Idee.

Je nachdem, was du da genau machen möchtest, könnte auch ein JSON-Parser interessant sein: JSON in JavaScript
 
Du übergibst JavaScript-Code mittels JSON? Das Format ist wirklich nur für Daten geeignet.
 
Jetzt verstehe ich erstmal, dass dort gar kein JSON geevelt() werden soll. Du willst alle übergebenen Werte des übergeben Objekts als Objekt-Eigenschaften speichern? Ist die frage, ob diese Eigenschaften sichtbar (public) oder unsichtbar (private) sein sollen.

Code:
function MyObject(new_data){
   var data = {
       myElement : "irgendwas",
       myString : "string"
   };

   // data und new_data angleichen
   for (var i in new_data) {
       data[i] = new_data[i];
   }

   // werte setzen
   // ausklammern für private
   for (var i in data) {
       this[i] = data[i];
   }

   this.getMyElement = function getMyElement() {
       return data.myElement;
   };
}
 
Moin.
Also was ich machen will ist, dass wenn Attribute hinzukommen nur noch diese im Kopf des Objektes definieren muss und man kann nun einen neuen Wert für das Attribut mitgeben, sodass es überschrieben wird.
Denn jedes Attribut abufragen und ansonsten einen dafault Wert zu setzen, wäre in meinem Fall sehr aufwendig, da ich ein Objekt mit ca 20 Attributen erstellen will :D
Deswegen dachte ich, ich könnte die Private Variablen mit Hilfe einer foreach und einem eval beschreiben.
Das funktioniert aber leider nur mit Strings.
Die Variante von crash würde ja funktionieren, jedoch hätte ich lieber die Daten nicht in einem Container. Falls da wem was einfällt bitte mal sagen :)

Hier mal meine aktuelle version:

PHP:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Untitled Document</title>
    <script type="text/javascript">
      
      function Editor(arg){
        var editorActive; // Boolean
        var element  = document.getElementsByName("body")[0]; // HTML-Element
        var defaultText; // String
                
        /**
         * Konstruktor
         * @param {Object} args
         */
        var __construct= function(args){
          // Alle mitgegeben Attribute setzen
                    for (var option in args) {
            var type = (typeof args[option]) + "";
            if (type.toLowerCase() != "string") {
              eval(option + " = " + args[option] + ";");
            }
                        // Wenn String dann auch als String setzen
            else {
              eval(option + " = \"" + args[option] + "\";");
            }
          }
        };
        
                /**
                 * Editor in Element erstellen
                 */
        this.createEditor = function(){
          element.innerHTML = "<p>Test</p>";
        };
                
                /**
                 * Gibt das Editor-Element zurück
                 */
                this.getElement = function() {
                    return element;
                };
                
                /**
                 * Gibt den Standardtext zurück
                 */
                this.getDefaultText = function() {
                    return defaultText;
                };
        
        
                // Konstruktor aufrufen
        __construct(arg);
      }
      
      window.onload = function(){
        var editor = new Editor({
          defaultText : "jojoo",
                    element : document.getElementById("edit")
        });
        alert(editor.getElement());
                alert(editor.getDefaultText());
      };
      
    </script>
  </head>
  <body>
    <div id="edit">
    </div>
  </body>
</html>
 
Ich war auch verwirrt. JSON ist die Bezeichnung für ein Format um Daten auszutauschen. Es basiert auf der JS schreibweise: JSON

Hier geht es lediglich um einen Funktionsparameter als Objekt, in der literalen Schreibweise.

Bezüglich der privaten Variabel, kommst du mit eval nicht an's Ziel, da eval immer im Kontext von window ausgeführt wird, du erzeugst also mit eval globale Variabeln.

Ich würd's vermutlich auch so wie Crash machen.

Aber ich bin in letzter Zeit am zweifeln ob das wirklich sinnvoll ist, da dieser Weg langsam ist. Wesentlich schneller ist diese Variante:
Code:
function MyObject(new_data){
	this._data = {
		myElement : "irgendwas",
		myString : "string"
	};
	for (var i in new_data) this._data[i] = new_data[i];
}
MyObject.prototype.getMyElement = function () {return this._data.myElement;};

Mit dem Nachteil, dass man keine echten privaten Werte hat, aber der Geschwindigkeitsvorteil ist - je nach Browser - enorm gross.
 
Und noch was, eine private Konstruktorfunktion in der Konstruktorfunktion ist irgendwie sinnfrei.
 
Und noch was, eine private Konstruktorfunktion in der Konstruktorfunktion ist irgendwie sinnfrei.
Der Konstruktor wird ja nur beim erstellen aufgerufen. Das lass ich ja in der letzten Zeile aufrufen, um somit eine Klasse vorzutäuschen ^^
Aber gut zu wissen, dass sich eval immer auf das window Objekt bezieht.
Dann ist das mit dem Datencontainer ja die beste Variante. Über was für Dimensionen der Geschwindigkeitseinbuße sprichst du hier, wenn ich die Variablen privat machen würde?
Da ich grade ein paar Web Aplikationen für Handybrowser (und sonstige kleine Geräte) am schreiben bin, ist das wohl von Vorteil, wenn ich da an geschwindigkeit gewinnen kann.

Ich danke euch allen für die guten Vorschläge :)

#Edit#
Ach wegen der frage warum ich die Attribute nicht so gern im Container hätte. So ist es bei anderen Sprachen ja auch nicht. Ich definiere die Attribute ja in der Regel auch im Kopfbereich der Klasse.
Aber wenn das nicht mit eval funktioniert, bleibt mir da ja schon fast nichts anderes :) (Außer jedes Attribut einzeln zu setzen)
 
Naja, der Konstruktor ist die Funktion MyObject(), deine Funktion __constructor() ist lediglich eine lokale Funktion innerhalb der Konstruktorfunktion. Du brauchst sowas nicht in JS.

Naja, ein Geschwindigkeitsvorteil ist immer relativ. Es kommt vor allem drauf an, wie oft du den Konstruktor aufrufen musst und welchen Browser du betrachtest. In Firefox hast du 200-300% Vorteil, Safari sind es nur ca. 50% und erstaunlicherweise im IE8 gar keinen.
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben