Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Переменная. идентификатор = инициализатор. (https://javascript.ru/forum/misc/2751-peremennaya-identifikator-%3D-inicializator.html)

Дроздов 07.02.2009 10:35

Переменная. идентификатор = инициализатор.
 
Уважаемые специалисты! Помогите пожалуйста дилетанту разобраться в этом js. Вопрос простой, вроде бы, но загнал в тупик...
в общем виде это выглядит — var идентификатор[=инициализатор]?[,идентификатор[=инициализатор]?]? и. т.д. (ну как обычно...) и ничего с этим поделать я не могу, ибо мозга не хватает.
А мне очень надо, чтоб как-то можно было передать идетификатор какой-то функции, а в идеале объекту, например: obj.идентификатор, этот объект его возвращает в случае наличия, а в случае undefined, делает из неё — obj.идентификатор = "идентификатор";

Для чего мне это надо...
Задача не сложная, мне надо сделать так, чтоб некоторые (или все) функции VBScript, можно было вставлять в js код. Все и сейчас работает, но оказалось, что функций хочется втыкать гораздо больше, чем вначале и ещё моя девочка сильно страдает, когда её заставляют на работе писать на js. Так вот я хочу сделать такую маленькую библиотечку, где основной набор (самые любимые VB функции) лежат в файле, а все прочие, которые может быть и не нужны вовсе - генерятся по мере надобности и только в конкретном куске кода. Сейчас вызов в общем случае выглядит так: VBS.func("InputBox")("бла-бла-бла...");, а мне надо, чтоб это было --VBS.InputBox("бла-бла-бла..."); так вот как сделать так, чтоб "на лету" можно было взять имя переменной и подсунуть его в её же значение?
Помогите! и тогда, может будет мне щастье?

Zeroglif 07.02.2009 12:04

Похоже речь о "bracket notation", VBS.InputBox можно задать как VBS['InputBox'] или в квадратных скобках может стоять имя переменной/выражение для нужной динамики. Или вы о другом?

Дроздов 07.02.2009 13:08

Не совсем. Наверное я как-то криво объяснил. Насчет добраться к методу или свойству так или эдак через --[], речь не идет, тут всё понятно. Я хочу имея VBA = {
func: function(func){ return VBS(func);},
} -- это на все случаи жизни, когда функция берет название нужной VB-функции (скажем "Int") из аргумента, ну и дальше там всё происходит само собой. т.е. сначала надо сказать, что Int = VBA.func("Int"), а потом уже можно эту свою Int юзать как Int(x). ну или сразу передать в функцию в виде func("Int")(x); если отправить сразу func(Int(x));, то скрипт ругнется в случае если Int undefined, т.е. её надо как-то сразу и объявить и присвоить, но в виде "Int"(x) совсем уж никуда не влезет.
Другими словами -- не строковый литерал передавать, а сразу переменную название которой и станет значением для аргумента функции.
может скритпта кусок проще показать?

Zeroglif 07.02.2009 13:40

Код плиз. Желательно на упрощённом (foo-bar-бла-бла-бла), но законченном! примере обрисовать проблему...

Дроздов 07.02.2009 14:14

сохранить как *.wsf и запускать.
<job id='vbs'>
<script language='VBScript'>
Sub VbsEval(expr): PutResult(Eval(expr)): End Sub
</script>

<script language='JScript'>
var VB = {}; 
var VB = { func: function(func){ return VBS(func);}}
function VBS(func) {
 PutResult = function(X) {EvalResult=X;}
 GetArgs = function(i) {return _fArgs[i];}
 this.f = new Function(
    '_fArgs=arguments;'+
    'var cnt = _fArgs.length, args=new Array(cnt);'+
    'for (var i=cnt; --i>=0;) args[i]="GetArgs("+ i +")";'+
    'VbsEval("' +func+ '("+args+")");'+
    'var retVal=EvalResult;'+
    '_fArgs=null; EvalResult=null;'+
    'return retVal;'
  );
  return f;
}

// здесь по-всякому их обозвать...
VB.StrReverse = VBS("StrReverse");
VB.Int = VBS("Int");
var InputBox = VBS('InputBox');

var reverse = VBS("StrReverse");
var x=InputBox("сюда не целое x", "вызвать VB InputBox из JScript");
VBS("MsgBox")("x = "+x+'\n'+reverse(x)+'\n'+VB.Int(x), 0,"VBS" ); //а можно и сразу прямо так, если функция в скрипте есть
</script>
</job>


но требуется -- объект лежит в библиотеке vbs.wsc (чтоб подтянуть как activX к любому js) и чтоб не заряжая его заранее всеми возможными vba функциями можно было достать их из объекта так: VBA.Int(x);, а не так как теперь: VBA.func("Int")(x);
вот тут мой мозг закончился...

Zeroglif 07.02.2009 16:12

Цитата:

достать их из объекта так: VBA.Int(x);, а не так как теперь: VBA.func("Int")(x)
Если смотреть по коду, то для вызова VB.Int() именно в таком виде, нужно, чтобы у объекта VB уже был соответствующий метод. Судя по всему такие методы не должны появляться заранее ("чтоб не заряжать"), а только по мере надобности, что делает VB.func(). Вы не хотите одновременно (а) создавать все методы заранее, (b) eval-ить лишний раз одно и то же. Отсутствующий метод нам не вызвать (если, конечно у IE нет что-нибудь вроде __noSuchMethod__), то есть его нужно или проверять и создавать при каждом вызове, или вызывать всё тот же общий VB.func(), но наполнять его новыми методами постепенно (VB[func]=f) по мере создания, чтобы потом не делать этого заново...

Дроздов 07.02.2009 17:43

Да совершенно верно, если метод есть, то ни каких трудностей, всё складывается нормально, но совершенно точно Вы сказали -- заранее создавать и каждый раз evalить по два раза это уже накладно. во-первых этот код нужно будет целиком инклюдить вместе с объектом и eval как я понимаю - дорогое удовольствие. Вот идея насчет наполнения по мере создания хороша, это было бы пожалуй красиво - добавлять метод по первому вызову в случае отсутствия. Только я не понял как она может реализоваться, если метод у объекта отсутствует? Если VB[func]=f, это же не значит что VB.f теперь объявится, всего лишь станет VB.func == f.
Или я чего-то не допонимаю?
Если не сложно поясните пожалуйста мысль, как его можно проверять создавать при вызове? Тут у меня уже тупик.

Zeroglif 07.02.2009 18:35

Аргументом в VB.func приходит строка, допустим, 'Int', вам нужно сразу проверить наличие одноимённого метода - если if(VB[func]) {...}, то сразу вернуть VB[func], если нет, то ваш этот eval через Function с одновременным созданием отсутствующего метода, который и возвращается как-нибудь так - return (VB[func] = Function(...)). Соответственно, последующие вызовы с этим аргументом VB.func('Int') не приведут к созданию функции...

Цитата:

Если VB[func]=f, это же не значит что VB.f теперь объявится, всего лишь станет VB.func == f.
Будет создан метод объекта VB с именем, взятым из func и значением из f.

Дроздов 07.02.2009 19:18

Ну да да, я сейчас всё это проделал, только в случае со строкой в аргументе всё получается как и прежде, а вот с undefined не получается.
Проще говоря:
если у VB нет метода Int --, то объявится он только если VB['Int'] = 'Int' (так оно и есть сейчас). Но в случае с VB.Int и при отсутствии Inrt как свойства или метода, ругается на undefined интерпритатор, ещё не доходя до объекта.
Я кажется понял, с js такой номер не пройдет, или же надо очень хитрым навороченным способом, как-то невидимо запустить браузер и через объект window что-то там химичить, а это уже перебор, а браузер здесь может и не учавствовать.
Цитата:

Сообщение от Zeroglif (Сообщение 12247)
Будет создан метод объекта VB с именем, взятым из func и значением из f.

вот если бы это название методу было взято сразу из самого имени func не прибегая ни где к назначению "func" -- задача бы решилась.
Спасибо Вам за участие.

Zeroglif 07.02.2009 19:34

var VB = {
    func: function (func){
        if (this[func]) {
            return this[func];
        } else {
            PutResult = function(X) {EvalResult=X;}
            GetArgs = function(i) {return _fArgs[i];}
            return (this[func] = new Function(
                '_fArgs=arguments;'+
                'var cnt = _fArgs.length, args=new Array(cnt);'+
                'for (var i=cnt; --i>=0;) args[i]="GetArgs("+ i +")";'+
                'VbsEval("' +func+ '("+args+")");'+
                'var retVal=EvalResult;'+
                '_fArgs=null; EvalResult=null;'+
                'return retVal;'));
        }
    }
}

//-> методов нет, буим создавать
var reverse = VB.func("StrReverse");
var x=VB.func("InputBox")("сюда не целое x", "вызвать VB InputBox из JScript");
VB.func("MsgBox")("x = "+x+'\n'+reverse(x)+'\n'+VB.func("Int")(x), 0,"VBS" );

//-> методы есть, можно к ним обращаться
var y=VB.InputBox("сюда не целое y", "вызвать VB InputBox из JScript");
VB.MsgBox("y = "+y+'\n'+VB.StrReverse(y)+'\n'+VB.Int(y), 0,"VBS" );


Часовой пояс GMT +3, время: 20:23.