2010-12-14 27 views
1

Vous cherchez un autre oeil pour rendre le Javascript suivant plus efficace.Plus efficace Javascript

Le JSON suivant est produit à partir d'un service Resteasy:

var testing = { 
    "com:klistret:cmdb:ci:pojo:successful":true, 
    "com:klistret:cmdb:ci:pojo:count":1, 
    "com:klistret:cmdb:ci:pojo:elements":{ 
     "com:klistret:cmdb:ci:pojo:id":123, 
     "com:klistret:cmdb:ci:pojo:name":"Mars", 
     "com:klistret:cmdb:ci:pojo:type":{ 
     "com:klistret:cmdb:ci:pojo:id":1, 
     "com:klistret:cmdb:ci:pojo:name":"Environment" 
     }, 
     "com:klistret:cmdb:ci:pojo:configuration":{ 
     "@www:w3:org:2001:XMLSchemainstance:type":"Environment", 
     "@Watermark":"past", 
     "com:klistret:cmdb:ci:commons:Name":"Mars" 
     } 
    } 
}; 

étendu le Extjs JSONReader pour traiter des profondeurs clés supérieur à 2 dans le procédé CreateAccessor. Vous vous demandez s'il existe un moyen de rendre le code plus efficace? La fonction ci-dessous s'appellera function(testing, "com:klistret:cmdb:ci:pojo:[email protected]") où la propriété com:klistret:cmdb:ci:pojo:elements est la racine.

createAccessor : function(){ 
    var re = /[\[\.]/; 

    return function(expr) { 
     if(Ext.isEmpty(expr)){ 
      return Ext.emptyFn; 
     } 

     if(Ext.isFunction(expr)){ 
      return expr; 
     } 

     # THIS FUNCTION I WANT TO BE EFFICIENT 
     return function(obj){ 
     while (String(expr).search(re) !== -1) { 
var i = String(expr).search(re); 
var key = expr.substring(0, i); 

if (obj.hasOwnProperty(key)) { 
    obj = obj[key]; 
} 

expr = expr.substring(i+1, expr.length); 
} 

      return obj[expr]; 
     }; 
    }; 
}() 
+0

Pourquoi votre analyse de code convertir expr à une chaîne deux fois par boucle et ne parviennent pas à le convertir en une chaîne avant d'appeler substring? La contrainte de chaîne ne peut-elle pas être déplacée complètement hors de la boucle? Idéalement, en dehors de la fonction interne aussi. –

Répondre

1

C'est ce que j'utilise. Je ne permets d'annotation de points, l'esprit:

Ext.override(Ext.data.JsonReader, { 
    createAccessor: function() { 
    return function(expr) { 
     if (Ext.isEmpty(expr)) { 
     return Ext.emptyFn; 
     } else if (Ext.isFunction(expr)) { 
     return expr; 
     } else { 
     return function(obj) { 
      var parts = (expr || '').split('.'), 
       result = obj, 
       part, 
       match; 
      while (parts.length > 0 && result) { 
      part = parts.shift(); 
      match = part.match(/^(.+?)(\[(\d+)\])?$/); 
      result = result[match[1]]; 
      if (result && match[3]) { 
       result = result[match[3]]; 
      } 
      } 
      return result; 
     } 
     } 
    }; 
    }() 
}); 
+0

A travaillé parfait .... merci pour la pointe (code plus propre aussi .... facile à lire) –

1

Une optimisation de base serait d'éviter le balayage de la chaîne deux fois avec search, ce qui est assez lent.

Le mieux que vous pouvez faire est de remplacer tout le balayage de la chaîne et l'extraction de sous-chaîne avec un seul appel à expr.split('.'), qui soutiendrait accesseurs de la forme aaa.bbb.ccc.ddd et les transformer en un tableau comme ['aaa','bbb','ccc','ddd']. Les deux autres caractères que vous semblez prendre en charge ([ et ]) ne fonctionneraient pas.

Alternativement, vous pouvez faire une correspondance initiale pour /[^\].[]+/g sur toute votre chaîne et conserver les correspondances pour obtenir un tableau similaire, mais cela pourrait être plus lent que la solution précédente.