2016-07-28 26 views
0

Ich habe eine Config als solche:faul Auswertung von Variablen in Javascript

hierarchy = { 
    // all different Geos 
    State: { 
     'dataSource' : $scope.stateData, 
     'class'  : 'stateContainer', 
     'fillColor' : 'red', 
     'stroke-width': 2 
    }, 
    County: { 
     'dataSource' : $scope.countyData, 
     'class'  : 'countyContainer', 
     'fillColor' : 'green', 
     'stroke-width': 1 
    } 
    // same for zip3, zip5 etc... 
    // config options list shortened for simplicity 
}; 

Dann gibt es die Zeichenfunktion, eine einzige Funktion, die den Namen, was nimmt Ich mag ziehen (Staat oder Landkreis oder. wie unten in Pseudo-Code ..) gezeigt:

function drawGeo(geoName) { 
    /* pseudocode */ 

    // this is OK 
    something.attr('class', hierarchy.geoName.class) 

    // not OK 
    var data = loadData(hierarchy.geoName.dataSource) 
} 

Der Grund für diese Konfiguration verwendet, ist für die Erstellung jedes geo (Staat eine eigene Funktion zu vermeiden, ...) und alle Zeichnungs Konfigurationen an einem Ort zu zentralisieren (anstatt Funktionsparameter rund um den Code und für jeden Funktionsaufruf zu verwalten).

Vorausgesetzt, dass hierarchy.geoName.class eine Zeichenfolge ist, verursacht es kein Problem beim Festlegen. Das Gleiche gilt für andere Konstanten wie stroke-width.

DataSource verursacht jedoch ein Problem, hauptsächlich weil $scope.stateData und $scope.countyData während der Erstellung der Hierarchiekonfiguration nicht definiert sind.

Ich suchte nach einer Möglichkeit, diese Variable "faul" zu machen, und sie nur zu holen, wenn auf sie zugegriffen wird (wie es in Scala und anderen Sprachen möglich ist).

Eine naheliegende Strategie wäre, die Variablen in der dataSource zwischen Anführungszeichen einzuschließen (sie werden stattdessen zu Strings). Dann holen den eigentlichen Inhalt der Variablen in der Auslosung Funktion eval:

'dataSource' : '$scope.stateData', 
... 

loadData(eval(hierarchy.geoName.dataSource)) // works 

Dies wird wahrscheinlich die eval anziehen() = böse Armee. Die Frage ist also:

  1. gegeben, dass der Inhalt von $ scope.geoData gesteuert wird, die Sicherheitsbedenken der eval keine Sorge sein sollte, nicht wahr? In diesem Fall sollte es sicher sein, eval() auf diese Weise zu verwenden?

  2. Gibt es andere Javascript-Möglichkeiten zu faul holen Variablen, die als weniger "böse" betrachtet werden würde?

  3. wenn "eval" in diesem Fall schlecht ist, irgendwelche anderen Vorschläge?

Vielen Dank!

+1

Ja, 'eval' ist hier böse (hauptsächlich weil es langsam ist, schwer zu debuggen und das falsche Werkzeug). Warum verwenden Sie nicht eine einfache Funktion, die Sie anrufen können? – Bergi

+0

ahh ich habe Ihre Kommentare zu verschiedenen ähnlichen Fragen gesehen :) Würden Sie bitte betonen, was Sie mit "einer einfachen Funktion, die Sie anrufen können" meinen? – Khorkhe

+0

Einfach '' dataSource 'machen: function() {return $ scope.stateData} 'und dann' loadData (hierarchy.geoName.dataSource()) '(oder nennen Sie es' getDataSource', oder machen Sie es einfach zu einer Getter-Eigenschaft) . – Bergi

Antwort

1

@ Beratung Bergi ist in den Kommentaren Folgende:

eval ist böse hier (vor allem, weil es langsam ist, schwer zu debuggen, und das falsche Werkzeug)

Stattdessen bringen Sie es in einer Funktion wie beispiels wie:

'dataSource': function() { return $scope.stateData } 

Dann rufen sie es mit:

loadData(hierarchy.geoName.dataSource()) 
+0

sicherlich sinnvoll für mich. +1 für neues Wissen: o –