Эй, ребята. Некоторое время я занимаюсь таким "шаблоном", но я не могу оценить этот архитектурный выбор. Мне кажется ужасным и бессмысленным кодом.
Я привожу вам пример кода, чтобы быть более объяснительным.
Все ли те IIFE, объявленные за пределами документа, готовы к плохой практике? Это шаблон или это просто спагетти JS? Любые слабые места или архитектурные ошибки?
Index.html
<html>
<head>
<meta HTTP-EQUIV='content-type' CONTENT='text/html; charset=utf-8'/>
</head>
<body>
<div id="first"></div>
<div id="second" style="border:2px solid green;width:150px;height:190px;"></div>
</body>
<script type='text/javascript' src='http://code.jquery.com/jquery-latest.min.js'></script>
<script type='text/javascript' src='js/scope.js'></script>
</html>
scope.js
(function() {
if (typeof $M === 'undefined') { $M = {}; }
var
$document = $(document);
$first = $('#first'),
$second = $('#second'),
$chunk = $("<div id='chunk'> truffle shuffle </div>"),
documentHeight = $document.height(),
animationTime = 1000,
style = {
'border':'2px solid red',
'height': documentHeight / 8,
'width': '150px'
},
style2 = {
'height': documentHeight / 4,
'width': '300px'
};
var init = function() {
$second.hide(); // init ops
}
function appendChunk() {
$first.append($chunk);
$chunk.css(style);
}
function animateChunk() {
$chunk.animate(style2,animationTime,function(){
$(this).trigger('animationComplete');
});
}
appendChunk();
animateChunk();
$M.one = init;
})();
(function() {
if (typeof $M === 'undefined') { $M = {}; }
var
$second = $('#second'),
$chunk = $("#chunk"),
animationTime = 1000,
style = {
'border':'2px solid red',
'height': '150px',
'width': '150px'
};
var init = function() {
$second.hide(); // init ops
}
$chunk.on('animationComplete',function(){
$second.fadeIn().trigger('animationComplete');
});
$second.on('animationComplete',function(){
$chunk.animate(style,animationTime);
});
var time = setInterval(function() {
if($second.is(':visible')) {
console.log("visible");
clearInterval(time);
} else {
$second.html("finished!");
}
},200);
$M.two = init;
})();
$(document).ready(function () {
$M.one();
$M.two();
});
Примечание. На момент написания этой статьи в вашем вопросе нет кода. Это сейчас, см. Ниже.
Все ли те IIFE, объявленные за пределами документа, готовы к плохой практике?
Совсем нет, они полезны для обзора.
Я обычно не использую JQuery ready
, потому что я предпочитаю просто положить script
элемент в нижней части страницы, поэтому я использую IIFE, чтобы избежать каких - либо глобал и быть noConflict
-compatible:
(function($) {
// My code here
}(jQuery);
(Теперь, когда в вопросе есть код...)
Но если вы беспокоитесь о плохой практике, вы должны отметить это:
if (typeof $M === 'undefined') { $M = {}; }
Это зависит от "Ужаса неявных глобалов" и, отдельно, несовместимо с "строгим" режимом ES5.
Здесь шаблон, который вы можете использовать для этой ситуации:
// By default, global scope is not strict
(function(global) {
// Now we turn on strict
"use strict";
if (typeof global.$M === 'undefined') { global.$M = {}; }
var $M = global.$M;
// ...
})(this);
Или в браузерах просто используйте window
:
(function() {
// Now we turn on strict
"use strict";
if (typeof window.$M === 'undefined') { window.$M = {}; }
var $M = window.$M;
// ...
})();
Большинство людей (или, по крайней мере, я!) Используют IIFE по следующим причинам:
Это очень полезно. Вы бы загрязняли среду вашего браузера бесполезными переменными для других файлов, поэтому вы переносите весь код внутри IIFE, и они не становятся глобальными, будучи доступными для всего кода внутри области функций. В принципе, это способ получить "частные вары" в JS.
Например, когда вы делаете следующее:
(function( window, document, undefined ) {
// ...
})( window, document );
Учитывая, что вы используете много этих трех переменных внутри этой области, ваш окончательный, уменьшенный файл будет намного меньше:
(function( a, b, c ) {
// code with all references to window, document and undefined renamed
})( window, document );
Надеюсь, это поможет вам понять, почему использовать IIFE.
Кроме того, всегда хорошо читать то, что Бен Альманн должен сказать о них. Он создатель Grunt.js :)