Более эффективный Javascript - PullRequest
1 голос
/ 14 декабря 2010

Ищите еще один глаз, чтобы сделать следующий Javascript более эффективным.

Следующий сервис JSON создается из сервиса 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"
      }
    }
 };

Расширение Extjs JSONReader для обработки глубины ключа выше 2 в методе createAccessor. Хотите знать, есть ли способ сделать код более эффективным? Следующая функция будет вызываться как function(testing, "com:klistret:cmdb:ci:pojo:configuration.@Watermark"), где свойство com:klistret:cmdb:ci:pojo:elements является корнем.

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];
        };
    };
}()

Ответы [ 2 ]

1 голос
/ 15 декабря 2010

Это то, что я использую. Я допускаю только точечную аннотацию, помните:

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;
        }
      }
    };
  }()
});
1 голос
/ 14 декабря 2010

Базовая оптимизация состояла бы в том, чтобы избежать сканирования строки дважды с помощью search, что довольно медленно.

Лучшее, что вы можете сделать, это заменить все сканирование строк и извлечение подстрок одним вызовом expr.split('.'), который будет поддерживать средства доступа вида aaa.bbb.ccc.ddd и превращать их в массив типа ['aaa','bbb','ccc','ddd'].Два других поддерживаемых вами символа ([ и ]) не будут работать.

В качестве альтернативы, вы можете выполнить начальное сопоставление для /[^\].[]+/g по всей вашей строке и сохранить совпадения, чтобы получить аналогичный массив, но это, возможно, будет медленнее, чем в предыдущем решении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...