Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Как лучше создавать динамическое имя переменной (http://www.flasher.ru/forum/showthread.php?t=181363)

dkart01 21.06.2012 16:27

Как лучше создавать динамическое имя переменной
 
Есть строчка
Код AS1/AS2:

_root.cam6.e3.onPress = function() {trace("yes");}

Мне нужно динамически менять цифры 6 и 3, какой способ наиболее лучше или может они оба устарели и вы сможете посоветовать более современный.

Код AS1/AS2:

i=6;
с=3;
 
// вар 1
_root["cam"+i]["e"+c].onPress = function() {trace("ter244");}
 
// вар 2
eval("_root.cam"+i+".e"+c).onPress = function() {trace("ter6");}


Hauts 21.06.2012 16:33

Лучше закэшировать значения и обращаться по ссылке.

Код AS1/AS2:

var cam_1 = _root.cam6.e3
var cam_2 = _root.cam3.e6
 
cam_1.onPress = ...

Если будет много клипов, то тогда уже в цикле прогонять или с массивами помудрить нужно будет. Но очевидно, что постоянно (не однократно) пользоваться динамическим доступом - зло.

Из ваших вариантов выбрал бы первый.

dkart01 21.06.2012 16:47

А можете подробнее про злые ситуации написать. В чём может быть злоупотребление и чем это грозит.

Hauts 21.06.2012 16:59

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

Для наглядного примера можете такое у себя попробовать:
Код AS1/AS2:

var a = {};
a.b = {};
a.b.c = {};
a.b.c.d = {};
a.b.c.d.e = {};
a.b.c.d.e.f = {};
a.b.c.d.e.f.someProp = 15;
 
var t = getTimer();
var s = 0
for (var k = 0; k < 1000000; k++) {
        s += a.b.c.d.e.f.someProp;
}
trace(getTimer() - t) // 4041
 
var t = getTimer();
var s = 0
var q = a.b.c.d.e.f
for (var k = 0; k < 1000000; k++) {
        s += q.someProp;
}
trace(getTimer() - t) // 3061

В комментариях значения, которые у меня получились. И да, представьте, что вместо a.b.c.d.e.f будут осмысленные переменные, по 10 - 12 символов каждая, — тут уж точно лучше закэшировать :)

Еще можно ссылки на клипы не просто перечислением var clip_1 = ... создавайть, а, например, в массив загонять для удобства.

Иными словами, чем больше операций происходит для доступа к камому-либо полю, тем хуже.

Код AS1/AS2:

eval("_root.cam"+i+".e"+c).onPress = ... // 4 операции
_root.cam3.e6.onPress = ... // 2 операции
cam_1.onPress = ... // без операций, если не считать количество операций при кэшировании


dkart01 21.06.2012 17:25

Тест дал:
2990 и 2305

Могли бы подсказать, что значат фигурные скобки после = ? И немножко подробнее скрипт расписать.
Мы в первом таймере один миллион переменных присваиваем?))))))

Hauts 22.06.2012 06:51

dkart01, фигурные скобки — это новый объект. То есть можно написать "{}", а можно и "new Object()". Аналогично можно и с массивами — вместо "new Array()" писать "[]".

В приведеном коде я создаю структуру, — у объекта "a" есть свойтво "b", тоже объект. У которого, в свою очередь, есть войство "c", которое тоже является объектом и т.д. И в итоге у свойства "f" (объекта) я создаю поле "someProp", равное 15.

Далее для теста я записываю в переменную t текущее значение таймера (таймер в миллисекундах и считается от начала запуска флэшки). Потом в цикле от 0 до 1000000 (миллион итераций) я прибавляю к переменной "s" значение "someProp" у объекта "f", при этом осуществляя прямой доступ к этому значение, то есть по "a.b.c.d.e.f.someProp". После выполнения цикла вывожу разницу между текущим значением таймера и тем, что я записал еще до начала цикла. Таким образом я получаю время в миллисекундах, потраченое на выполнение этого кусочка кода.

Аналогично и во втором тесте, только там я предварительно закэшировал структуру объектов в отдельную ссылку "q" и в цикле уже обращаюсь через "q.someProp".

Разница в значениях потраченого времени из-за того, что в первом случае используется прямой доступ, а во втором — по ссылке. Если написать третий тест еще и с динамическим доступом, то его результаты будут самыми плохими.

dkart01 22.06.2012 10:58

Здорово. Очень хороший пример!


Можно попросить вас помочь с объектами (пример ниже). Один из случаев применения - кэширование, а какие еще могут быть применения таким объектам?
Мувиклип - частный случай объекта?
Код AS1/AS2:

var a = {};
a.b = {};
a.b.c = {};
a.b.c.d = {};
a.b.c.d.e = {};
// a.b.c.d.e = 3;  Так нельзя делать?  Присвоить значение можно только последнему объекту в цепочке?
a.b.c.d.e.f = {};
a.b.c.d.e.f.someProp = 15; // последний объект или переменная, не знаю как правильно


Hauts 22.06.2012 12:36

Хм. Считайте, что объект (new Object() я имею в виду) — это просто хранилище для свойств и методов. Мувиклип — это тоже объект, только визуальный. Меняя свойство "_x" у объекта-мувиклипа, вы увидете изменение положения графики на экране. Вообще все в экшенскрипте основывается на объектах.

Применений множество для объектов. Я только некоторые случаи могу привести, которые сходу на ум приходят.

1. Использование объекта в качестве аргумента для функции в случае, если количество необходимых аргументов непредсказуемо:
Код AS1/AS2:

function generateSomeStroke(o) {
        var returnStroke = "";
        for (var i in o) {
                returnStroke += i + "=" + o[i] + "&";
        }
        return returnStroke.substr(0,-1)
}
var myObject = {};
myObject.param_1 = "hello!";
myObject.param_2 = 10;
myObject.param_3 = true;
myObject.param_4 = {};
 
trace(generateSomeStroke(myObject));

2. Использование объектов для хранения данных по ключам:
Код AS1/AS2:

var data = {};
for(var k = 0; k < 100; k++){
    data["someFieldName_" + k] = {someProp: k + 10}
}

— здесь в цикле от 0 до 100 у объекта "data" будут создаваться свойства (ключи) со значением равным новому объекту со свойством someProp.

Так же можно перебирать все свойства объекта в цикле:
Код AS1/AS2:

function traceObject(o){
    for(var i in o){
        trace(i + " = " + o[i]);
    }
}
var myObject = {}
myObject.param_1 = "hello!";
myObject.param_2 = 10;
myObject.param_3 = true;
myObject.param_4 = {};
 
traceObject(myObject);

Ну а вообще, если вам нужен перебор по числу — намного лучше использовать массивы, конечно.

Добавлено через 2 минуты
Код AS1/AS2:

var a = {};
a.b = {};
a.b.c = {};
a.b.c.d = {};
a.b.c.d.e = {};
a.b.c.d.e = 3;
a.b.c.d.e.f = {};
a.b.c.d.e.f.someProp = 15; // последний объект или переменная, не знаю как правильно

Сначала вы создаете объект "e" — a.b.c.d.e = {};, а потом переписываете его значением "3" (числом). Далее вы уже у числа 3 пытаетесь создать свойство "f", но такого не получится, у числел нельзя свойства создавать. Соответственно f и f.someProp не будут существовать.


Часовой пояс GMT +4, время: 19:04.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.