Условно определить функции в современных браузерах?Esp Safari? - PullRequest
0 голосов
/ 19 октября 2018

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

Я вижу, что Safari 12 (iOS 12.0.1 и macOS 10.14) неправильно определяет условные функции, в то время как Chrome, Firefox, Edge, кажется, делают правильные вещи.Кроме того, какова спецификация правильного поведения для движка JS, чтобы я мог сообщить об этой ошибке в Apple, если она есть.

Справочная информация: Мы делаем это, чтобы избежать загрузки Google Analytics (gtag.js), еслипользователь не дает согласия на GDPR.Код инициализации Google gtags.js содержит строку function gtag(){dataLayer.push(arguments);}, которая отключает Safari.

Код ниже, демонстрация на JS Fiddle здесь

<html>
  <head>
    <title>Safari JS engine test</title>
    <script type="text/javascript">
      if (false) {
        function conditionalFunctionality() {
          alert("Doing conditional functionality");
        }
      }
      window.onload = function() {
        if (typeof conditionalFunctionality === "function") {
          alert("BAD. It's defined");
        } else {
          alert("GOOD. It's NOT defined");
        }
      }
    </script>
  </head>
  <body>
    <h1>Safari JS engine test</h1>
  </body>
</html>

Mugshots

iOS macOS

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

Как указано в комментариях выше, определения функций могут вести себя не интуитивно, когда они не являются «верхним уровнем».Например:

a()
function a() { console.log("here"); }

войдет в консоль, даже если определение функции появится после ее использования.Это называется подъем в Javascript, и хорошее описание доступно здесь:

https://gomakethings.com/function-expressions-vs-function-declarations/

(любезность pointy )

Разные версии браузера выполняют эту функцию по-разному, что приводит к несогласованности, которую вы наблюдаете, и почему «строгий» режим (т. Е. Наличие "use strict"; в верхней части блока кода изменяет это поведение).

Когда я хочу получить подобное поведение, я склонен использовать «выражения функций».Что будет выглядеть примерно так:

var conditionalFunctionality;
if (false) {
  conditionalFunctionality = function () {
    console.log("conditionally defined");
  }
}
if (conditionalFunctionality) {
  conditionalFunctionality();
}

, который также имеет то преимущество, что имеет естественную «ложную» переменную в зависимости от ситуации и не требует играть в какие-либо typeof conditionalFunctionality === "function" игры.

0 голосов
/ 19 октября 2018

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

В этом сообщении stackoverflow подробно рассказывается о том, как обнаружить определенные браузеры, поэтому я не буду повторятьсячто здесь: Как определить браузер Safari, Chrome, IE, Firefox и Opera?

затем можно написать что-то вроде

function f(...) {
    if (isSafari()) {
        // Safari specific stuff
    else {
        // other stuff
    }
}

, где функция isSafariявляется оберткой вокруг чека из сообщения stackoverflow, на которое я ссылался.

РЕДАКТИРОВАТЬ: было отмечено, что вы хотите, чтобы это основывалось на конкретной функциональности, а не на браузерах.В этом случае вы должны заменить isSafari в моем примере выше соответствующей функцией, чтобы проверить, поддерживает ли текущий браузер желаемую функциональность, а не проверять тип браузера.

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

...