Что это за строка вверху некоторых скриптов Greasemonkey?


Справочная информация: У меня есть уровень самоучки-любителя понимания C++, который перевел в аналогичное понимание javascript. В попытке лучше понять javascript я решил написать сценарий Greasemonkey, который решил бы проблему с тем, как Google обрабатываетнесколько результатов из одного домена .

Я написал свой сценарий, и это оказалось на удивление легко. Теперь я чувствую, что этот сценарий может быть полезен другим, поэтому я хотел бы выпустить его. Прежде Чем Я тем не менее, я хотел бы быть уверенным, что я не выпускаю безответственный код. Я знаю, что плохая сборка мусора часто упоминается как проблема с расширениями, и провел некоторые исследования о том, что мне нужно сделать в javascript, чтобы предотвратить это. Похоже, что ответ заключается в том, что любая память, которая обернута в функцию, будет возвращена, когда эта функция выйдет. Это, кажется, объясняет, почему несколько популярных сценариев, которые я смотрел, были обернуты в бесполезную функцию.

Это ведет меня на эти вопросы:

  1. что я должен сделать с моей основной функцией javascript, чтобы гарантировать, что она не будет пропускать память?
  2. Это, который я видел во многих сценариях, ответ:

    (function(){  
        //code goes here    
    })();
    
  3. В приведенном выше коде какова цель первых скобок? Мне это кажется излишним.

  4. Пока я пытался понять эту строчку, я переписал ее так:
    (function main(){  
        //code goes here  
    })   
    main();  
    

Идея в том, что это было просто вызовом the ранее безымянная функция. Но это не сработало, почему?

Меня больше интересуют общие ответы, но в случае необходимости вот мой текущий код: http://pastebin.com/qQWKfnJT

3 6

3 ответа:

Этот паттерн (обертывание функции в пару скобок и затем размещение другой пары после первой пары) называется " I mmediately I nvoked F unction E xpression" паттерн (IIFE для краткости). Что он делает, так это определяет анонимную функцию и немедленно ее выполняет. Первый набор скобок обозначает функцию как выражение , а не оператор. Второй набор выполняет функцию, возвращенную из первое выражение:

// This:
(function(){
    // Todo: Add code
})();

// Translates *approximately* to this:
var _anonymous_function_2723113 = function() {
    // Todo: Add code
};
_anonymous_function_2723113();
delete _anonymous_function_2723113;
Что касается того, почему функция не работает, когда вы даете ей имя, я бы рекомендовал прочитать статьюkangaxx на эту тему , особенно там, где он касаетсяименованных выражений функций . Короче говоря, когда у вас есть именованное выражение функции (а не оператор), имя предполагается доступным только для области видимости функции.

Столько для трех и четырех - как для избегания памяти утечки, IIFE-это не способ избежать утечек памяти (как указал @elclanrs, это просто помогает вам избежать загрязнения глобальной области). Чтобы избежать утечек памяти, избегайте циклических ссылок (и помните, что замыкания могут быть источником циклических ссылок).

Удачи вам и наслаждайтесь жизнью!

Есть так много ответов на этот вопрос в SO уже... Это самоисполняющаяся функция. Он используется во многих случаях для защиты кода от глобальной области видимости. Это написано и другими способами:

function(){}()
(function(){})()
(function(){}())
!function(){}()
(function(){}).call(this)

Вот пример, где можно использовать анонимные функции: Пусть имеется 4 элемента с идентификаторами: id_1, id_2, id_3... Мы хотим тоже зациклиться на каждом из них и назначить событие onclick.

for (var i=0; i<5; i++) {
    document.getElementById("id_"+i).onclick = function()  {alert(i)}
}

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

for (var i=0; i<5; i++) {
(function(n){
    document.getElementById("id_"+n).onclick = function() {alert(n)};
})(i);

}