Действительно ли необходим шаблон выражения немедленного вызова функций (IIFE) при написании пользовательских скриптов? - PullRequest
3 голосов
/ 23 июня 2019

Мой вопрос очень похож на Какова цель самоисполняющейся функции в javascript? , но вместо этого она касается пользовательских скриптов (специально для GreaseMonkey).

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

Пример сценария с шаблоном IIFE: (источник)

// ==UserScript==
// (...)
// ==/UserScript==

(function(){
    // if <condition>
        document.location.href += '?sk=h_chr';
    // ...
})();

Пример сценария без него: (источник)

// ==UserScript==
// (...)
// ==/UserScript==

window.location.href = "https://www.facebook.com/?sk=h_chr";

Кроме того, я также обнаружил, что за ним следует шаблон «Новый скрипт» от TamperMonkey, а шаблоны от GreaseMonkey и ViolentMonkey - нет.

Вопрос в том, полезен ли шаблон IIFE при написании пользовательских скриптов?

Особенно, если мой скрипт находится в режиме strict , и я использую let вместо var.В любом случае, насколько мне известно, функции и переменные, определенные в пользовательских скриптах, не доступны в глобальной области страницы.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 23 июня 2019

В общем, нет;шаблон IIFE редко полезен для обертывания всего пользовательского сценария (см. крайние случаи ниже).Это был возврат ко многим годам назад, когда некоторые движки (кратко) не переносили сценарии по умолчанию.

Фактически, если вы включите устаревшую директиву @unwrap , все механизмы сценариев теперь будут игнорировать ее.

Вот несколько причин использовать шаблон IIFE:

  • В настоящее время это единственный способ включить режим strict в Violentmonkey (только) для всего сценария.Но это упущение только для этого одного двигателя, и, надеюсь, скоро будет исправлено.
  • Это может подавить безвредное Parsing error: 'return' outside of function предупреждение , если вы используете ОБА: (1) Общий сценарий return и (2) внешний LINTer.
    Некоторые старые версии Greasemonkey также предупреждают об этом, хотя все еще работают отлично.
  • (я думал, что был случай с 3-м краем)Но был прерван и не могу вспомнить, что это было.)

Рассмотрим этот тестовый скрипт:

// ==UserScript==
// @name     _Scope and Strict-Mode Demo script
// @match    https://stackoverflow.com/*
// @unwrap
// @grant    none
// ==/UserScript==
/* eslint-disable no-multi-spaces, curly */
'use strict';

if (location.pathname.includes("/users/") ) {
    console.log ("Terminating script early.");
    return;  // In external LINTers, this will cause a harmless warning.
}

var cantSeeMeInConsole      = "neener neener";
window.canSomestimesSeeMe   = "Howdy";

console.log (`In Strict mode: ${bInStrictMode() }; \`cantSeeMeInConsole\`: ${cantSeeMeInConsole}`);

function bInStrictMode () {
    var inStrict = false;
    var dummyObj = {};
    Object.defineProperty (dummyObj, 'foo', {value: "bar", writable: false } );

    try { dummyObj.foo = "fee"; }
    catch (e) { inStrict = true; }
    return inStrict;
}
  • Запустите на Firefox иChrome.
  • Safari и Opera должны давать одинаковые результаты.
  • Microsoft Edge , вероятно, дает одинаковые результаты. (Но мне все равно, если это не так.)
  • Беги, используя Tampermonkey, Violentmonkey и Greasemonkey 4.

Область действия сценария:

Во всех случаях сценарий пользователя ограничен.На странице не видны ни код, ни переменные типа cantSeeMeInConsole.
Остерегайтесь того, что конфликты страниц сценариев могут по-прежнему происходить в режиме @grant none.

Изолированная среда сценариев:

Дополнительные изоляции применяются в зависимости от: (a) механизма пользовательских сценариев, (b) браузера и (c) режима @grant.
Например, использование Greasemonkey или изменение режима предоставления убивает страницуспособность видеть canSomestimesSeeMe.

Строгий режим:

  • В Tampermonkey и Greasemonkey, размещение 'use strict'; вверху, как это, переводит весь пользовательский скрипт в строгий режим.
  • В некоторой степени ошибка в том, что этого не происходит в Violentmonkey.
  • Кроме того, в расширенных настройках Tampermonkey вы можете установить для «строгого режима» значение [По умолчанию / Всегда / Отключено] для всехscripts.

В соответствующей заметке, если сценарий не использует настройки @run-at, нет смысла использовать $(document).ready() или его сокращение.

0 голосов
/ 23 июня 2019

функции и переменные, определенные в пользовательских скриптах, не доступны в глобальной области страниц

Это не так.

Работа пользовательских скриптов осуществляется путем внедрения скрипта (да, это в основном атака).Единственный способ, которым пользовательские скрипты могут получить доступ к переменным и функциям на странице, - это открыть пользовательские скрипты на странице - таким образом, у страницы есть доступ к пользовательскому скрипту.

Поэтому главная причина использования IIFE в пользовательских скриптах - избегатьиспортить скрипты, запущенные на странице.

Некоторая система внедрения скриптов может прозрачно выполнить ваш пользовательский скрипт во IIFE за вашей спиной (это то, что nodejs делает с модулями - да, это не пользовательский скриптсистема, но это пример программного обеспечения, которое делает это).В таких случаях вам не нужно вручную кодировать IIFE самостоятельно.Лично я не знаю, какое расширение делает это, а какое нет, поэтому я склонен включать IIFE просто для безопасности.

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

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