Обработка массива JavaScript - дополнение ActiveX против FF - PullRequest
1 голос
/ 27 мая 2011

Вопрос

Существует ли чистый и надежный способ обработки вызовов к плагину, чтобы вызывающая сторона всегда могла ожидать, что ему будет возвращен массив JavaScript, независимо от того, используется ли плагинтакое дополнение Firefox или элемент управления ActiveX?У меня уже есть фактические вызовы плагинов, заключенные в функции, например:

function getDevice(deviceKey) {
    return plugin.getDevice(deviceKey);
}

Я могу изменить его на что-то вроде:

function getDevice(deviceKey) {
    return normalizeArray(plugin.getDevice(deviceKey));
}

function normalizeArray(array) {
    return typeof(array) == 'unknown' ? array.toArray() : array;
}

, но мне все еще нужно помнить, чтобы на самом деле вызватьnormalizeArray из функций-оболочек, и реализация нормализации может показаться, что ей не хватает надежности и / или сделаны некоторые подозрительные предположения.

Есть ли лучший способ справиться с этой ситуацией?

Справочная информация

Я пишу некоторый JavaScript для взаимодействия с плагином через JavaScript.Плагин доступен как дополнение в FF и как ActiveX в IE.В плагине есть несколько методов, которые возвращают массивы.В FF вызов:

typeof(retVal);

для объекта возвращает 'объект'.Я могу делать такие вещи, как:

retVal.length;
retval[0];

, и они работают как положеноКогда я делаю те же самые вызовы методов в IE, вызов:

typeof(retVal);

возвращает значение unknown и такие вызовы, как:

retVal.length;
retval[0];

не определены.

Я имеювыполнил некоторую отладку и обнаружил, что ActiveX действительно возвращает массив вариантов.Этот объект распознается JScript, и версию массива JavaScript можно получить, вызвав retVal.toArray ().

1 Ответ

1 голос
/ 27 мая 2011

Я бы сделал нормализацию массива частью оболочки, но оставил бы ее как отдельную функцию так:

function getDevice(deviceKey) {
    return normalizeArray( plugin.getDevice(deviceKey) );
}

Вы правы, функция normalizeArray кажется немного хрупкой. Вместо этого вы можете захотеть сделать instanceof тест и даже обернуть его в try..catch, поскольку IE, как известно, делает странные вещи, когда объекты ActiveX тестируются таким образом, поэтому:

function normalizeArray(obj) {
  try {
    if (obj instanceof Array) {
      return obj;
    }
  } catch(d) {}

  // Convert obj to array - see if toArray property is truthy
  if (obj.toArray) {

    // Is this syntax correct?
    // If it is, call it
    return obj.toArray();

  } else {

    // Not Array, no toArray(), what next?

  }
}

Однако я не уверен, является ли объект, возвращаемый вашим плагином Firefox, массивом javascript или он создается в той же области, что и функция normalizeArray (т.е. он может быть создан из другого конструктора Array ) поэтому тест instanceof не будет выполнен, даже если это массив. Альтернативный тест:

Object.prototype.toString.call(obj) == '[object Array]'

который, я думаю, определенно должен быть заключен в try..catch для IE, если есть вероятность obj является объектом ActiveX.

Кстати, typeof - это оператор, нет необходимости использовать оператор группировки ().

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