Какая из этих кросс-браузерных функций Javascript работает лучше? - PullRequest
3 голосов
/ 12 марта 2009

Как правило, какой из этих методов написания кросс-браузерных функций Javascript будет работать лучше?

Метод 1

function MyFunction() 
{
    if (document.browserSpecificProperty)
       doSomethingWith(document.browserSpecificProperty);
    else
       doSomethingWith(document.someOtherProperty);
}

Метод 2

var MyFunction;
if(document.browserSpecificProperty) {
    MyFunction = function() {
       doSomethingWith(document.browserSpecificProperty);
    };
} else {
    MyFunction = function() {
       doSomethingWith(document.someOtherProperty);
    };
}

Редактировать: Upvote за все хорошие ответы до сих пор. Я исправил функцию в более правильном синтаксисе.

Пара замечаний по поводу ответов на данный момент - хотя в большинстве случаев это довольно бессмысленное повышение производительности, есть несколько причин, по которым можно по-прежнему тратить время на анализ кода:

  • Должен бежать дальше медленные компьютеры, мобильные устройства, старые браузеры и т. д.
  • Любопытство
  • Используйте то же самое общий принцип к производительности улучшить другие сценарии, где оценка заявления IF делает занять некоторое время.

Ответы [ 7 ]

16 голосов
/ 12 марта 2009

Если вы не делаете это триллион раз, это не имеет значения. Выберите тот, который более читабелен и удобен в обслуживании для вас и / или вашей организации. Повышение производительности, которое вы получите от написания чистого, простого кода, имеет значение гораздо больше, чем сокращение одной десятой микросекунды от вашего времени выполнения JS.

Вы должны даже начинать думать о том, что лучше , когда и только когда вы написали код, и это недопустимо медленно. Тогда вы должны начать искать узкое место, которое никогда не будет таким. Вы никогда не получите ощутимого прироста производительности при переключении с одного на другое здесь.

7 голосов
/ 12 марта 2009

К сожалению, приведенный выше код на самом деле не подходит для разных браузеров, так как он опирается на причуду mozilla, отсутствующую в других браузерах, а именно: function операторы обрабатываются как function выражения внутри веток. В браузерах, отличных от Mozilla, приведенный выше код всегда будет использовать определение второй функции. Я сделал простой тестовый пример, чтобы продемонстрировать это здесь .

По сути, спецификация ECMAScript гласит, что операторы функций обрабатываются аналогично объявлениям var, например. все они поднимаются на вершину текущей области выполнения (например, начало тега , начало функции или начало блока eval).

3 голосов
/ 12 марта 2009

Чтобы уточнить ответ olliej, ваш второй метод технически является синтаксической ошибкой. Вы можете переписать это так:

var MyFunction;
if(document.browserSpecificProperty) {
    MyFunction = function() {
       doSomethingWith(document.browserSpecificProperty);
    };
} else {
    MyFunction = function() {
       doSomethingWith(document.someOtherProperty);
    };
}

Какой по крайней мере правильный синтаксис, но учтите, что MyFunction будет доступна только в той области, в которой это происходит. (Пропустите var MyFunction; и предпочтительно используйте window.MyFunction = function() ... для глобального.)

2 голосов
/ 12 марта 2009

Технически, я бы сказал, что второй будет работать лучше, потому что оператор if выполняется только один раз, а не каждый раз, когда функция запускается.

Разница, однако, будет незначительной до такой степени, что она будет бессмысленной. Снижение производительности одного оператора if, такого как это, было бы незначительным даже по сравнению с потерей производительности простого вызова функции. Это имело бы небольшую разницу, даже если бы оно вызывалось миллион раз.

Первый легче понять, потому что у него нет неловкости в том, чтобы определять одну и ту же функцию дважды на основе условия, причем обе версии ведут себя по-разному. Это, кажется, рецепт путаницы позже.

Я бы не первый, кто скажет, что если вы действительно не сошли с ума по поводу этой оптимизации, вы получите большую выгоду от читабельности кода.

0 голосов
/ 14 марта 2009

Производительность должна быть почти равной!

Об использовании Frameworks, например JQuery, чтобы избавиться от проблем совместимости браузера!

Если производительность является вашей главной целью, взгляните на SlickSpeed ​​! Это страница, которая сравнивает различные JavaScript-фреймворки!

0 голосов
/ 14 марта 2009

Для вашего упрощенного примера я бы сделал следующее, предполагая, что проверку свойств вашего браузера нужно выполнить только один раз:

var MyFunction = (function() {

      var rightProperty = document.browserSpecificProperty || document.someOtherProperty;

      return function doSomethingWith() {
            // use the rightProperty variable in your function
      }
})();
0 голосов
/ 12 марта 2009

Я обычно предпочитаю вторую версию, поскольку условие должно оцениваться только один раз, а не при каждом вызове, но бывают случаи, когда оно неосуществимо, потому что оно ухудшает читабельность.

Кстати, это тот случай, когда вы можете использовать оператор ?:, например (взят из производственного кода):

var addEvent =
    document.addEventListener ? function(type, listener) {
        document.addEventListener(type, listener, false);
    } :
    document.attachEvent ? function(type, listener) {
        document.attachEvent('on' + type, listener);
    } :
    throwError;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...