- PVSM.RU - https://www.pvsm.ru -
Привет!
Всем известно решение задачи загрузки скриптов.
Например Curl.JS, Require.JS, + популярные frameworks умеют это тоже.
Вот и недавно была статья [1] про это от уважаемого azproduction [2].
Но все же интересно, есть ли альтернативы AJS, CJS, etc, учитывая ссылку [3].
Что если есть возможность загрузить JavaScript забыв про обыденные «мелочи» типа:
define( function(){
return MyBeautifulObject;
});
Пример для самых нетерпеливых. [4]
Далее небольшая заметка о том как это работает.
Началось всё вот с такой бесполезной конструкции:
var fn = ( function(){
var ffn = Function.apply( this, arguments ) ;
var init = this;
return ( function( ffn ){
alert( '1: '+init )
alert( '2: '+this )
var zfn = function(){
alert( '3: '+init )
alert( '4: '+this )
return ffn.apply( init, arguments );
};
return zfn;
}).call( init, ffn );
} ).apply( 456, [ 'a', 'b', ' alert(a+b); alert( "this: " + this ); return this; ' ] );
alert( 'result: ' + fn.call( 123, 5, 5 ) );
JS Fiddle [5]
Потом, постепенно трансформировалось в это:
var fns = ( function(){
var fn = new Function( 'with( this ){ return ' + Function.apply( this, arguments ).toString() + '; }' );
fn = fn.call( this );
return function(){
return fn.apply( this, arguments );
};
} ).apply( { bb: 789 }, [ 'a', 'b', ' alert(a+b); alert(this); alert( "bb: " + bb ); return bb; ' ] );
alert( 'result: ' + fns.call( 123, 5, 5 ) );
JS Fiddle [6]
Как видно из кода, через with определяется ссылка на примесь из переданного в scope объекта: bb.
И, наконец, финальный код загрузчика скриптов в виде метода для jQuery:
(function( jQuery, undefined ){
jQuery.loadSubScript = function( url, scope, thisName, returnCallback ){
// если не передан scope сделаем его глобальным
var scope = scope || window;
// аналогично
var thisName = thisName || window;
$.ajax( {
url: url
, type: 'GET'
, dataType: 'text'
, success: function( data ){
try{
// создаем полученный код, не забываем про with
var fns = new Function(
'with( this ){ return '
+ Function.apply( null, [ data ] )
+ '; }'
);
// инициализируем замыкание с with
fns = fns.call( scope );
// инициализируем замыкание с this
var turn = fns.call( thisName );
// возвращаем результат в callback, если он есть
returnCallback && returnCallback( turn );
}catch(e){ alert(e); }
}
, error: function( jqXHR, textStatus, errorThrown ){
alert('Loader Error:n' + errorThrown );
}
} );
};
})( jQuery );
Тот же самый пример для Терпеливых. [4]
Что можно?
Конечно, если что нибудь будет нести var, то оно будет внутри созданного замыкания. Без var, как и должно быть — попадет в window. То, что является методами переданного в scope объекта будет доступно без точки. С this — всё как обычно, в случае его подмены.
Пользуйтесь на здоровье!
Ссылка на GIT [7]
Можно рассказать коллеге.
Best Regards!
PS: Не знаю какую лицензию выбрать, наверное MIT + GPLv3.
Автор: wentout
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/9443
Ссылки в тексте:
[1] статья: http://habrahabr.ru/post/145269/
[2] azproduction: http://habrahabr.ru/users/azproduction/
[3] ссылку: http://tomdale.net/2012/01/amd-is-not-the-answer/
[4] Пример для самых нетерпеливых.: http://wentout.github.com/SubScriptLoader/
[5] JS Fiddle: http://jsfiddle.net/YEC3w/
[6] JS Fiddle: http://jsfiddle.net/Nh7uN/
[7] Ссылка на GIT: https://github.com/wentout/SubScriptLoader
Нажмите здесь для печати.