26

Re: JScript: Фреймворк

dab00 пишет:

Наверное подразумевали Number.prototype.

Точно. Это у меня опечатка.

greg zakharov пишет:

Диапазон знакового целочисленного типа, насколько помню, лежит в пределах от -2147483648 до 2147483647, и если попытаться определить тип этих значений с помощью оператора typeof, получим Number. Следовательно, определить самостоятельно целочисленный тип в JavaScript более, чем возможно, правда есть несколько нюансов, например, как идентифицировать Integer без приведения к таковому с помощью parseInt?

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


var x = Math.PI;
alert(x >>> 0);
alert(x >> 0);
alert(x << 0);
alert(x ^ 0);
alert(x | 0);

Вcе они а) отбрасывают дробную часть числа, б) обнуляют результат, если число по модулю превышает 0xFFFFFFFF (2^32-1), Но здесь есть одна тонкость: числа больше 0x7FFFFFFF можно рассматривать как отрицательные так и положительные. Например, 0x80000001:


0x80000001 >>  0 == -2147483647
0x80000001 >>> 0 == 2147483649

Справедливо и обратное:


-1 >>  0 == -1
-1 >>> 0 == 4294967295

Иногда может потребоваться одно, иногда - другое.

Rumata пишет:

..."валить" в все в одну кучу - не есть хорошо.

greg zakharov пишет:

Позвольте заметить, что конечное слово все же за разработчиком. Единственное, на что действительно стоит обратить внимание в данном случае - доступность документации.

Согласен с Вами. Но ограниченный набор отдельных файлов, каждый из которых содержит определенный, ограниченный функционал, лучше, чем один сплошной файл. Если есть зависимости (фнукционал файла А зависит от некотрых функций файла Б)  - задокументировать в шапке файла.

Так любой сможет с легкостью использовать часть функционала не вытягивая всю библиотеку (например, если кому-то захочется использовать "массивные" функции forEach, map и прочие в реализации JSMan, то он, кто-то легко разберется, что искомое находится в файле Array.js).

Serge Yolkin пишет:

...не загоняясь по синтаксису других языков. Таким образом, ForEach и each из разных фреймворков-трансляторов могут ссылаться на один и тот же код базового фреймворка.

Для меня здесь ключевая фраза - "не загоняясь по синтаксису других языков". Думаю, что не стоит приближать один язык к другому. JS от этого лучше не станет, если он будет похожим на AutoIt. Если кто-то желает програмировать на JS, похожем на AutoIt, может быть он выбрал не тот язык для программирования? В частности, для меня Ruby далек, так же как Cobol, поэтому первые ассоциации при виде each связаны с jQuery, в котором он реализован через абы как - передача параметров прямо противоположна стандартному forEach. Вот пример (об чем думал Джон?):


var x = [1, 2, 3];
$.each(x, function(index, value) { alert(value); });

x.forEach(function(value, index) { alert(value); });
JSman пишет:

что есть "базовый" js-фреймворк?:) Это сборище функций, которое я сам придумаю?.

Согласен полностью. Фактически, фреймворк - это некий набор готовых утилит, методов, оторые упрощают разработку. В теме уже несколько раз упоминался Closure, поэтому разделение на файлы весьма логично, коли лишнее будет удалятся автоматически на этапе сборки.

( 2 * b ) || ! ( 2 * b )

27

Re: JScript: Фреймворк

Rumata пишет:

...хак, но изящный...

Ну хорошо, а смысл плодить псевдотипы? Вот скажите, на JavaScript написано немало кода, но при этом никто не жаловался на отсутсвие целочисленных типов со знаком или без оного, - смысл ныне браться за перераспределение типов? Игры со смещением таковыми и останутся, если они неприменимы на практике, а на практике, еще раз повторю, никто не заморачивается отсутсвием некоторых типов в JavaScript. Саму же идею можно вполне взять на карандаш.

Rumata пишет:

Согласен с Вами. Но ограниченный набор отдельных файлов, каждый из которых содержит определенный, ограниченный функционал, лучше, чем один сплошной файл. Если есть зависимости (фнукционал файла А зависит от некотрых функций файла Б)  - задокументировать в шапке файла.

Простите, но идея классов мной уже выдвигалась, однако была отвергнута, поэтому еще раз повторюсь - давайте с уважением отнесемся к мнению автора темы.

Rumata пишет:

Думаю, что не стоит приближать один язык к другому.

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

Serge Yolkin пишет:

Остальные, как Ruby, например, можно отдать на откуп энтузиастам...

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

28 (изменено: Rumata, 2013-11-16 19:08:50)

Re: JScript: Фреймворк

greg zakharov

Ну хорошо, а смысл плодить псевдотипы?

Я то лично противник этого. Но речь шла именно о

greg zakharov пишет:

определить самостоятельно целочисленный тип в JavaScript более, чем возможно, правда есть несколько нюансов, например, как идентифицировать Integer без приведения к таковому с помощью parseInt?

Поэтому я и привел то решение. Кому надо - тот воспользуется и напишет свою реализацию определения целого числа.

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

Ни в коей мере не отвергаю мнение ни автора (JSMan в данном случае), ни чье-либо другое (Ваше). Речь только о разделении единого файла на этапе разработки на неколько отдельных файлов. Которые проще сопровождать и проще использовать отдельно.

Фреймворк в данном случае по сути является оберткой над встроенными средствами языка, реализующим функции AutoIt

Так ли необходимо реализовывать функционал одного языка в другом с точностью до API? Не лучше ли использовать другой язык? Например, в своей работе я использую очень часть Perl и JScript. Будучи на win-машине, использую js, если мне достаточно его средств, либо перехожу на Perl, если решение на нем быстрее проще в реализации и сопровождении. Тем более если это сиюминутная задача, то я возьму Perl (иногда JS, потому что мне не нравится работа с временем в Perl). Но я не создаю фреймфорк perl2js.
Но это только мое мнение. Каждый язык имеет свои средства работы с существующими объектами. дублирование классного средства одного языка в другом должно быть органично в рамках данного языка. Например, есть несколько реализаций C-подобной функции sprintf в js. Можно использовать существующее готовое, можно переписать с нуля. Задача стоит в API - как использовать функцию: sprintf("форматирующая строка", аргументы) или "форматирующая строка".sprintf(аргументы). В данном случае оба варианта хороши, но второй - более js-подобный.
Автор же волен решать свои задачи, если они ему необходимы. Тем более если в массах они найдут отклик.

( 2 * b ) || ! ( 2 * b )

29

Re: JScript: Фреймворк

В общем, довольно интересно почитать рассуждения. Конечно, всем не угодишь. У каждого опыт разный. Я несколько загрузился по теме "что же является базовым фреймворком". Рассуждения привели к следующему.

С одной стороны, говорят необходимо разбить на модули все функции, которые связаны с массивами, строками, числами, файловой системой. На самом же деле, следуя такой логике, должен появиться отдельный файл работы с реестром (что сводится по сути к 5 функциям), работы с вебом http (опять же до 5 функций), работа с процессами (3-4 функции) и т.п. А к чему это приведет?

Код разработчика, который работает с файловой системой, интернетом, а также мапит массив, обязан включить следующий код:


var AR = include("array.js");
var FS = include("filesystem.js");
var Inet = include("http.js");

То есть, по такой логике, я должен досконально знать какая именно функция находится в каждом файле фреймворка. Зачем нам такая модульность?

Окей, продолжу рассуждение. Функций же полно? А языки разные. Как делить будем? Придется либо в коде каждой тематической библы помечать из какого языка функция, либо создавать модуль типа <Язык_программирования>.<Модуль>. Каждый файл опять же надо будет изучать разработчику. Сколько инклудов будет в коде разработчика? Тьма. Запутаемся все. Основных функций для разработчика вполне достаточно не более 100.

Так что же все-таки можно назвать базовой частью фреймворка?
Базовая часть фреймворка, то бишь его основа — это те функции, которые нужны в первую очередь разработчику. А это означает, что разработчику нужно работать и со строками, с массивами, файловой системой, интернетом и т.п. Значит основной модуль должен это все включить в себя.

Рассмотрим псевдо-код (на базе разрабатываемого фреймворка), который является решением этой темы:


FileCopy( FileFind("%USERPROFILE%", /\.mab$/), "\\\\server\\mab\\name.mab");

а если вообще пофантазировать, то получится такое:


FileCopy( FileFind("%USERPROFILE%", /\.mab$/), @"\\server\mab\name.mab");

Не правда ли просто? И таких примеров решений на форуме можно привести полным-полно. Даже с инклудами играть не хочется.

Я понимаю, если, допустим, кто-то захочет реализовать работу с облаком Яндекс.Диск, Google Drive, FTP. Вот тогда - да. Модуль определенно нужен. Потому что модуль не должен у разработчика отбирать "основной" функционал, он преподносит ему дополнительный/изолированный функционал.

Что касается псевдо типов, то по мне это все надуманно. Кому реально нужны integer, float? Каков смысл? Но научить typeof отличать объект от array необходимо.

Далее, что касается sprintf. Rumata, идеологически я предпочитаю оба варианта. Неиспользуемое все равно при обработке будет выпилено. Не бойтесь избыточности.

В общем, подведу маленький итог своих рассуждений. То, что написано в первом топике, а также в секции To Do - это будет базовым фреймворком, плюс кое-что еще. Трансляторы языков — об этом рано говорить. Взять тот же perl. Реально под него все с нуля надо будет писать. Что поделаешь.

У меня вопрос к разработчикам. Хорошо, ну вот поделим сейчас базовую часть на string.js, array.js, fs.js, process.js, base.js. Что дальше будет? Сразу начнем программировать? :-D

UPD: Обновил.

+ открыть спойлер

StringCompare Compares two strings with options.
StringInStr Checks if a string contains a given substring.
StringIsAlNum Checks if a string contains only alphanumeric characters.
StringIsAlpha Checks if a string contains only alphabetic characters.
StringIsASCII Checks if a string contains only ASCII characters in the range 0x00 - 0x7f (0 - 127).
StringIsDigit Checks if a string contains only digit (0-9) characters.
StringIsFloat Checks if a string is a floating point number.
StringIsInt Checks if a string is an integer.
StringIsLower Checks if a string contains only lowercase characters.
StringIsSpace Checks if a string contains only whitespace characters.
StringIsUpper Checks if a string contains only uppercase characters.
StringIsXDigit Checks if a string contains only hexadecimal digit (0-9, A-F) characters.
StringLeft Returns a number of characters from the left-hand side of a string.
StringLen Returns the number of characters in a string.
StringLower Converts a string to lowercase.
StringMid Extracts a number of characters from a string.
StringRight Returns a number of characters from the right-hand side of a string.
StringStripCR Removes all carriage return values ( Chr(13) ) from a string.
StringStripWS Strips the white space in a string.
StringTrimLeft Trims a number of characters from the left hand side of a string.
StringTrimRight Trims a number of characters from the right hand side of a string.
StringUpper Converts a string to uppercase. Asc Returns the ASCII code of a character.

30

Re: JScript: Фреймворк

Как эта ф-я работает/должна работать?

// Add ECMA262-5 Array methods if not supported natively
//
if (!('indexOf' in Array.prototype)) {
    Array.prototype.indexOf= function(find, i /*opt*/) {
        if (i===undefined) i= 0;
        if (i<0) i+= this.length;
        if (i<0) i= 0;
        for (var n= this.length; i<n; i++)
            if (i in this && this[i]===find)
                return i;
        return -1;
    };
}

даже, если заменить знак "<" на ">" в последнем if , то она всегда будет возвращать индекс элемента массива
начиная с 0. Зачем тогда параметр i?

var myArr = ["aaa", "bbb", "ccc"];
myArr.indexOf('ccc', 0);             // вернёт 2
myArr.indexOf('ccc', 1);             // вернёт также 2...

31 (изменено: Rumata, 2013-11-18 10:52:35)

Re: JScript: Фреймворк

Зачем тогда параметр i?

поиск с заданной позиции:


x = ['a', 'b', 'c', 'a', 'b']
x.indexOf('b') // == 1
x.indexOf('b', 2) // == 4

Можно реализовать поиск всех вхождений заданного элемента.

( 2 * b ) || ! ( 2 * b )

32

Re: JScript: Фреймворк

Rumata пишет:

поиск с заданной позиции:


x = ['a', 'b', 'c', 'a', 'b']
x.indexOf('b') // == 1
x.indexOf('b', 2) // == 4

Можно реализовать поиск всех вхождений заданного элемента.

Дык не работает же... о том и пишу....

33

Re: JScript: Фреймворк

im2002, покажите код. Я проверил, все работает.

34

Re: JScript: Фреймворк

Обновил первый пост. Не смотря на большую занятость, разработка мелкими шажками продолжается. Код на HTA полностью функционирует.

Первый этап скоро добью. Осталось порядка 50-60 функций, но это пустяки. Затем, покажу реализацию отброса неиспользуемых функций, чтобы результирующий код был как можно компактнее и проще.

35 (изменено: dab00, 2014-03-28 07:41:46)

Re: JScript: Фреймворк

JSman пишет:

Не смотря на большую занятость, разработка мелкими шажками продолжается

Хочу познакомить с одной интересной находкой - Traceur.
Если правильно понял - пишем на ES6 - компилируем в ES3. По-моему в тему. Сорри, пока сам не пробовал.

36

Re: JScript: Фреймворк

dab00, в точку :-). Это и есть третий этап.

37

Re: JScript: Фреймворк

Работа не стоит на месте.

Решена проблема избыточного кода. Урезается на ура. Остается разобраться с удалением неиспользуемых методов прототипов.

Итак, в первую очередь вам понадобится Google Closure.
Файл compiler.jar расположите рядом с со скриптовым файлом compiler.js. Код compiler.js приведен ниже.

Для работы бросьте ваш скрипт на compiler.js и получите оптимизированный для исполнения код.


// compiler.js
// если осуществлялся запуск скрипта без параметра, то завершаем работу.
if (WScript.Arguments.length == 0) WScript.Quit();

var WshShell = new ActiveXObject("WScript.Shell");

var FileName = WScript.Arguments(0); // путь файла для обработки.
var FileNameTmp =  GetScriptDir()+GenerateString(12); // временный файл для сохранения промежуточного результата
var FileNameOut =  (/\./.test(FileName) ? FileName.replace(/\.[^\.]+$/, ".out.js") : (FileName + ".out.js")); // путь файла с результатами

var FSO = new ActiveXObject("Scripting.FileSystemObject");
var ForReading = 1,
    ForWriting = 2,
    ForAppending = 8;

// аналог VB-MsgBox в JS
function MsgBox(strText, strTitle, nType) {
    return WshShell.Popup(strText, 0, strTitle, nType);
}

//генерирует строку из случайных символов латиницы цифр.
function GenerateString(L) {
    if (!L) L = 8;
    return new ActiveXObject('Scriptlet.TypeLib').Guid.replace(/[^\w]+/g, "").slice(0, L);
}

// отображаем значение s в диалоговом окне. При нажатии на "отмена" осуществляется выход из кода. 
function alert(s)
{
    return;
    if (MsgBox(s, "", 1)==2) WScript.Quit();
}

//возвращает директорию расположения скрипта
function GetScriptDir() {
    return GetScriptFullPath().replace(/[^\\]+$/g, "");
}

//возвращает имя скриптового файла. Универсально для HTA и WSH.
function GetScriptFullPath() {
    if (this.location && this.location.href) return location.href.replace(/^.+\/\/\//, "").replace(/\//g, "\\");
    if (this.WScript) return WScript.ScriptFullName;
    return "";
}

//устанавливаем директорию нахождения скрипта в качестве рабочей. 
WshShell.CurrentDirectory = GetScriptDir();

// Открываем файл и читаем код
var f = FSO.OpenTextFile(FileName, 1, 0, -2);
var source = f.ReadAll();
f.Close();

//парсим js-код, выявляем конструкции языка: регулярные выражения, комментарии, строковые литералы.
//на выходе имеем двухуровневый массив [тип_конструкции][значение].
var tmp = ParseJS(source);

var resFile = FSO.OpenTextFile(FileNameTmp, 2, 1);

//выявляем методы и свойства объектов в коде и меняем их синтаксическое написание так: asd.e() -> asd["e"]()
// сохраняем это в промежуточном файле.
resFile.Write(Replacer(tmp));
resFile.Close();

// запускаем GoogleClosure для обработки временного файла и сохраняем в выходной файл.
WshShell.Run("%WinDir%\\System32\\java.exe -jar \""+GetScriptDir()+"compiler.jar\" --js \""+FileNameTmp+"\" --formatting=pretty_print  --compilation_level ADVANCED_OPTIMIZATIONS --use_only_custom_externs --use_types_for_optimization --js_output_file \""+FileNameOut+"\"", 1, 1);
FSO.DeleteFile(FileNameTmp, true)

MsgBox("Результаты сохранены в файле: " + FileNameOut);
WScript.Quit();

//функция парсинга js. code - текстовый фрагмент, который будет обработан
//парсим js-код, выявляем конструкции языка: регулярные выражения, комментарии, строковые литералы.
//на выходе имеем двухуровневый массив, где элемент - это [[тип_конструкции], [значение]].

function ParseJS(code) {
    var tmp = code, // копия code, которая будет обрабатываться и изменяться в процессе парсинга.  
        found = "", // строка с найденной начальной конструкцией языка
        startpos = 0,
        result = []; // результирующий массив
    var searchValues = /\/\*\[?|["']|\/\/|(?:(^|[;\}\{\(=!\?]|return)\s*)\/(?![\*\/])/m;
    var types = { 
        '/*': "comment",
        '/*[': "resource",
        '"': "string",
        "'": "string",
        '//': "comment",
        "/": "regexp"
    }; // типы конструкций языка


// находим точку начала входа в конструкцию
    function getStartPointOfValues(m) {
        
        var t=0;
        found = m;
        var pos = arguments[arguments.length-2];
               
        if (/[^\/]\/$/.test(m)) {
            found = "/"; t=m.length-1;
        }
        
        result.push(["code", tmp.slice(0,pos+t)]);
        alert(tmp.slice(0,pos));
        
        tmp = tmp.slice(pos + m.length);
    }

// находим точку окончания конструкции языка
    function getEndPointOfValues(m) {
        var pos = arguments[arguments.length-2];
        var content = tmp.slice(0, pos);
        
        result.push([types[found], found+tmp.slice(0,pos + m.length)]);
        tmp = tmp.slice(pos + m.length);
    }

// функция перебора кода
    function findValues() {
        tmp.replace(searchValues, getStartPointOfValues);

        if (found == '"') tmp.replace(/(?:^"|(?:\\\\|[^\\])")/, getEndPointOfValues);
        if (found == "'") tmp.replace(/(?:^'|(?:\\\\|[^\\])')/, getEndPointOfValues);
        if (found == '//') tmp.replace(/[\r\n]/, getEndPointOfValues);
        if (found == '/*' || found == '/*[') tmp.replace(/\*\//, getEndPointOfValues);
        if (found == "/") tmp.replace(/(?!\\).\//, getEndPointOfValues);
        found = "";
        return tmp;
    }

    //Перебираем содержание.
    while (tmp != findValues()) {}
    result.push(["code",tmp]);
    tmp = "";
    return result;
}


function Replacer(strct)
{
    var result=[];
    
    for (var i=0, l=strct.length; i<l; i++)
    {
        if (strct[i][0] == "code") result.push(strct[i][1].replace(/\.\s*([\$_a-z0-9]+)/ig, '["$1"]'));
        else result.push(strct[i][1]);
    }
    return result.join("");
}

На здоровье!

Что касается предложения с множеством тематических файлов (например, string.js, array.js и т.п.) для облегчения разработки, то оно скоро будет реализовано. Постараюсь использовать гитхаб (увы, не привык). А вообще, пора уже добить проект :-)

38

Re: JScript: Фреймворк

Функция подключения модулей.

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

Немного предисловия. Ядро фреймворка состоит из нескольких файлов, функции которых будут лежать в глобальном пространстве. Большая часть функций ядра перечислена в посте № 1.

Далее, я сделал возможность не только расширения глобального объекта, но и возможность замкнуть это на свой объект.


var GlobalObject = this;

// Include.Libs - словарь модулей
// Include.DefaultNameSpace - область видимости по умолчанию
function Include(JsPath, NameSpace)
{
    var method, module, lib, code, stream;
    var FSO = new ActiveXObject("Scripting.FileSystemObject");
    var WshShell = new ActiveXObject("WScript.Shell");
    
    JsPath = WshShell.ExpandEnvironmentStrings(JsPath);
    // если файла нет, то оканчиваем работу
    
    if (FSO.FolderExists(JsPath)) 
    {
        var files = new Enumerator(FSO.GetFolder(JsPath).Files);
        var scripts = [];
        for (; !files.atEnd(); files.moveNext())
        {
            if (/\.js$/i.test(files.item())) scripts.push(files.item());
        }
       
        for (var i=0; i<scripts.length; i++) Include(scripts[i], NameSpace);
        return true;
    }
    
    if (!FSO.FileExists(JsPath)) return false;
    // избавляемся от относительных путей, формируем полный путь. 
    JsPath = FSO.GetFile(JsPath).Path;
    // устанавливаем пространство имен, на которое будет распространяться импортируемый модуль.
    // если оно не задано в функции, то испортируемые функции подключаются к глобальному объекту (точнее к указателю this).
    if (!arguments.callee.DefaultNameSpace)arguments.callee.DefaultNameSpace = GlobalObject;
    if (!NameSpace) NameSpace = arguments.callee.DefaultNameSpace;
    if (!arguments.callee.Libs) arguments.callee.Libs = {};
    lib = arguments.callee.Libs[JsPath];
    // если модуль ранее подгружался
    if (lib) 
    {
        // то импортируем уже загруженные указатели функций модуля в объект, который кеширует перечень функций
        // нужна оптимизация, которая предотвратит повторное присвоение функций в namespace
        for (method in lib)
        {
            NameSpace[method]=lib[method];
        }
        return true;
    }
    else 
    {
        lib = arguments.callee.Libs[JsPath] = {};
        // если библиотека не подгружалась ранее, то осуществляется ее чтение и интерпретация
        if (FSO.GetFile(JsPath).Size==0) return "";
        stream = FSO.OpenTextFile(JsPath, 1, 0, -2),
        code = stream.ReadAll();
        stream.Close();
        module = eval("("+code+")");
        // далее, данные помещаются и в кеш, и в namespace
        for (method in module)
        {
            lib[method]=module[method];
            NameSpace[method]=module[method];
        }
    }
    return true;
}

   
Include("test3.js");
A();

var s = {};
Include("test3.js", s);
s.A();

Include.DefaultNameSpace = GlobalObject;     
(function(){
    Include("test3.js");
    A();
}
)();

Модуль выглядит примерно так:


(
(function (){
    MsgBox("Hello from module")
}
)(),

{
A : function () {
    MsgBox("123");
},

B : function () {
}

}
)

Как мы видим есть функция инициализации, которая будет вызвана только один раз, в какой бы неймспейс модуль не подключался бы. Экземпляры функций при разных неймспейсах не создаются дополнительно. Все кешируется. Объектам раздаются указатели на функции. Принципиально отказался от приватных переменных.

Теперь ядро фреймворка разделяю на файлы, чтобы можно было легко их проверять на корректность.

Есть проблема отладки, так как используется eval.
Также будет добавлена проверка конфликта имен функций модуля.

39

Re: JScript: Фреймворк

Черновик фреймворка и кодогенератора. В результате будет создан файл output.js без лишних функций.


Include("core");

function Main()
{
    FileCreateShortcut(GetWindowsDir() + "\\explorer.exe", GetDesktopDir() + "\\cmd.exe.lnk", GetWindowsDir(), "/e,c:\\", "Tooltip description of the shortcut.", GetSystemDir() + "\\shell32.dll", "CTRL+ALT+t", "15", 7);
    var res = FileGetShortcut(GetDesktopDir() + "\\cmd.exe.lnk");
    MsgBox(res);
    res[0]=GetWindowsDir() + "\\System32\\calc.exe";
    FileCreateShortcut.apply(null, res);
    res = FileGetShortcut(GetDesktopDir() + "\\cmd.exe.lnk");
    MsgBox(res);
    Exit();
}


FwBuildCode("Main", "output.js");
Exit();

// Include.Libs - словарь модулей
// Include.DefaultNameSpace - область видимости по умолчанию
function Include(JsPath, NameSpace)
{
    this.GlobalObject = this;
    var method, module, lib, code, stream;
    var FSO = new ActiveXObject("Scripting.FileSystemObject");
    var WshShell = new ActiveXObject("WScript.Shell");
    
    JsPath = WshShell.ExpandEnvironmentStrings(JsPath);
    // если файла нет, то оканчиваем работу
    
    if (FSO.FolderExists(JsPath)) 
    {
        var files = new Enumerator(FSO.GetFolder(JsPath).Files);
        var scripts = [];
        for (; !files.atEnd(); files.moveNext())
        {
            if (/\.js$/i.test(files.item())) scripts.push(files.item());
        }
       
        for (var i=0; i<scripts.length; i++) Include(scripts[i], NameSpace);
        return true;
    }
    
    if (!FSO.FileExists(JsPath)) return false;
    // избавляемся от относительных путей, формируем полный путь. 
    JsPath = FSO.GetFile(JsPath).Path;
    // устанавливаем пространство имен, на которое будет распространяться импортируемый модуль.
    // если оно не задано в функции, то испортируемые функции подключаются к глобальному объекту (точнее к указателю this).
    if (!arguments.callee.DefaultNameSpace)arguments.callee.DefaultNameSpace = GlobalObject;
    if (!NameSpace) NameSpace = arguments.callee.DefaultNameSpace;
    if (!arguments.callee.Libs) arguments.callee.Libs = {};
    lib = arguments.callee.Libs[JsPath];
    // если модуль ранее подгружался
    if (lib) 
    {
        // то импортируем уже загруженные указатели функций модуля в объект, который кеширует перечень функций
        // нужна оптимизация, которая предотвратит повторное присвоение функций в namespace
        for (method in lib)
        {
            NameSpace[method]=lib[method];
        }
        return true;
    }
    else 
    {
        lib = arguments.callee.Libs[JsPath] = {};
        // если библиотека не подгружалась ранее, то осуществляется ее чтение и интерпретация
        if (FSO.GetFile(JsPath).Size==0) return "";
        stream = FSO.OpenTextFile(JsPath, 1, 0, -2),
        code = stream.ReadAll();
        stream.Close();
        module = eval("("+code+")");
        // далее, данные помещаются и в кеш, и в namespace
        for (method in module)
        {
            lib[method]=module[method];
            NameSpace[method]=module[method];
        }
    }
    return true;
}

https://mega.co.nz/#!xpY2DaAI!0Wf0FycvN … ymnU5NP8oE

40 (изменено: Parazit, 2017-02-24 12:20:47)

Re: JScript: Фреймворк

Подскажите, а где есть самые полные справочники по всем методам и свойствам JScript и VBScript?

Желательно, на русском языке.