Я создаю компрессор JavaScript, и я нахожусь на стадии «сжатия локальных переменных». Я сравнивал результаты моего компрессора с различными онлайн-компрессорами и заметил кое-что интересное с Дином Эдвардсом /packer/.
Давайте возьмем этот фрагмент библиотеки jQuery в качестве примера:
(function( window, undefined ) {
var document = window.document,
navigator = window.navigator,
location = window.location;
});
Мой компрессор возвращает следующий код:
(function(a,b){var c=a.document,d=a.navigator,e=a.location});
но / packer / возвращает это:
(function(a,b){var c=a.document,navigator=a.navigator,location=a.location});
Есть ли причина, по которой / packer / не сжимает переменные после первой в списке переменных? Это просто ошибка или есть причина?
На первый взгляд может показаться, что мой компрессор работает правильно и даст лучший конечный результат, однако давайте посмотрим на другой пример из библиотеки jQuery:
var jQuery = (function() {
var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
},
// some other vars
rootjQuery;
// etc...
});
Этот фрагмент важен, потому что переменная rootjQuery
упоминается до ее определения.
В этом случае / packer / делает то же самое и сжимает только первую переменную в списке:
var jQuery=(function(){var c=function(a,b){return new c.fn.init(a,b,rootjQuery)},rootjQuery});
Однако мой компрессор немного испортил код, потому что, хотя он не сжимает rootjQuery
, когда он упоминается в операторе возврата (потому что он еще не определен), он сжимает его, когда он будет определен позже.
var jQuery=(function(){var a=function(b,c){return new a.fn.init(b,c,rootjQuery)},b});
Это, очевидно, вызывает ошибку при попытке выполнить код.
Есть ли способ обойти это? Похоже, что Дин Эдвардс заметил эту проблему, так что обошел ее, сжав только первую переменную в списке, чтобы в нечетном случае, когда такой случай всплывал, он не вызывал ошибку.
Я пытался выделить переменные, которые используются до их определения, и не сжимать их, но это не так просто, потому что в этом случае rootjQuery
используется в другом объеме, чем он определен. У меня нет возможности узнать, в какой области он будет определен, пока я не доберусь до него.