Эта функция используется непосредственно на этапе инициализации для встроенных
ActionScript-объектов. Она скрывает потомков объекта от цикла for..in.
Цикл for..in обрабатывает всех потомков объекта, как методы, так
и свойства. ASSetPropFlags также используется для защиты встроенных
потомков ActionScript-объектов от перезаписи и удаления. Есть польза от этой функции
и для разработчиков, особенно когда эта функция дает интересные результаты..
ASSetPropFlags может использоваться для:
Сокрытия потомков объекта от цикла for..in
Отмены скрытия потомков объекта от цикла for..in
Установки для потомков объекта защиты от переназначения
Снятия с потомков объекта защиты от переназначения
Защиты потомков объекта от удаления
Снятия защиты от удаления с потомков объекта
Поскольку эта функция была обнаружена, создаваемая ею защита от переназначения
и удаления становится бесполезной, потому что вы можете теперь сами контролировать
защиту; то же верно и для скрытия от цикла for..in — вы можете
отменить скрытие. Но если Macromedia может использовать это для дела, значит,
и мы тоже можем.
Функция ASSetPropFlags принимает четыре аргумента:
ASSetPropFlags(obj, props, n, allowFalse)
Первый аргумент obj — это объект, на который будет
действовать функция.
Второй аргумент props — это список имен потомков объекта,
передающийся как аргумент 'obj' в виде разделенной запятыми строки
или массива, на который будет воздействовать функция. Если в качестве этого аргумента
передать значение 'null', эффект будет то же, что и при передаче
массива со списком всех потомков, содержащихся в объекте, переданном как аргумент
'obj'. Например,
["start","stop","reset"]
Подействует на потомков с именами "start", "stop"
и "reset" так же, как
"start,stop,reset"
Третий аргумент n — это число,
представляющее три поразрядных флага, определяющих, какие именно изменения произойдут
со списком имен потомков: скрытие/отмена скрытия, установка/снятие защиты от переназначения,
установка/снятие защиты от удаления. В следующей таблице описаны результаты, получаемые
при разных возможных значениях этого аргумента:
Таблица 1: Результаты примения различных значений аргумента "
n"
Значение
аргумента |
Биты-
флаги |
Переназначение
запрещено? |
Удаление
запрещено? |
Скрыт ли
потомок? |
| 0 |
000 |
Нет |
Нет |
Нет |
| 1 |
001 |
Нет |
Нет |
Да |
| 2 |
010 |
Нет |
Да |
Нет |
| 3 |
011 |
Нет |
Да |
Да |
| 4 |
100 |
Да |
Нет |
Нет |
| 5 |
101 |
Да |
Нет |
Да |
| 6 |
110 |
Да |
Да |
Нет |
| 7 |
111 |
Да |
Да |
Да |
|
Четвертый аргумент allowFalse — это булеан (true/false),
определяющий, может ли быть установлено значение false для трех типов
защит — защиты от переназначения, защиты от удаления, и скрытия от циклов
for..in. Если этот аргумент опущен, используется значение по умолчанию
"false", означающее, что нельзя снимать защиту от переназначения,
нельзя снимать защиту от удаления и нельзя отменять скрытие от циклов for..in.
Внимание! Важное уточнение по использованию четвертого аргумента функции ASSetPropFlags можно найти на сайте Нокса, читайте: Рецепт: использование функции ASSetPropFlags() для защиты свойств и методов.
ASSetPropFlags была впервые обнаружена в Flash 5, и тем не менее,
четвертый аргумент "allowFalse" не требовался, так как
он всегда имел значение по умолчанию "true". Когда был
выпущен Flash MX, народ проверил, существует ли все еще эта функция, — очевидно,
она существовала, так как умные люди среди бета-тестеров использовали эту функцию,
чтобы получить список всех недокументированных объектов, методов, свойств и функций,
присутствующих в Flash MX:
//отменить скрытие всех потомков,
//содержащихся внутри объекта _global
//см. таблицу 1, чтобы определить результат
//воздействия третьего аргумента,
//имеющего значение "6"
ASSetPropFlags(_global,null,6,true);
//обработать всех потомков
//объекта _global
for(i in _global){
trace(i)
}
Вот что получается на выходе:
CustomActions
MMSave
Cookie
System
Accessibility
Video
Stage
TextFormat
TextField
Button
Key
Mouse
Selection
XML
XMLNode
Sound
Math
Array
String
Date
Boolean
Number
o
clearInterval
setInterval
isFinite
isNaN
updateAfterEvent
trace
parseFloat
parseInt
unescape
escape
ASSetNative
ASSetPropFlags
LocalConnection
SharedObject
Microphone
Camera
NetStream
NetConnection
Color
AsBroadcaster
XMLSocket
LoadVars
MovieClip
Infinity
NaN
Function
Object
ASconstructor
ASnative
Тем не менее, если повторить цикл for..in над всеми потомками
объекта _global, не произведя перед этим отмены скрытия:
for(i in _global){
trace(i);
}
То на выходе получим пустоту:
Все встроенные объекты имеют методы и свойства, скрытые от цикла for..in,
даже недокументированные скрытые объекты. Так, если бы мы хотели обнаружить, что
содержится в объекте NetConnection, мы могли бы сделать так:
//отменить скрытие всех потомков
//прототипа объекта NetConnection
ASSetPropFlags(NetConnection.prototype,null,6,true);
//обработать всех потомков
//прототипа объекта NetConnection
for(i in NetConnection.prototype){
trace(i);
}
Интересный получается результат:
addheader
call
close
connect
__proto__
constructor
Итак, существует процесс, которому вы можете следовать, чтобы достигнуть желаемых
результатов: сначала выберите объект, на который Вы хотите воздействовать как
на "obj", затем выберите потомков этого объекта, на которых
вы хотите воздействовать, и создайте массив "props" этих
имен, затем выберите результат поведения потомков, которого вы хотите достигнуть
(можно подобрать правильную величину аргумента "n" по приведенной
таблице). А затем если Вы хотите выключить любую из защит: отмена скрытия от for..in,
снятие защиты от удаления, снятие защиты от переназначения — передавайте
четвертый аргумент как булево значение "true" (в противном
случае просто опускайте этот аргумент).
Давайте создадим объект, содержащий некоторые свойства и методы, на которых
мы протестируем другие поведения этой функции:
//создайте новый объект
myproperties={};
//создайте несколько внутренних свойств объекта
myproperties.firstname="Guy";
myproperties.surname="Watson";
myproperties.icq=71063418;
Теперь давайте попробуем на этом объекте другие модели поведения. Сначала давайте
посмотрим, что произойдет, когда мы обработаем потомков этого объекта прежде,
чем использовать функцию ASSetPropFlags. Мы сделаем этот код функцией,
чтобы потом было проще использовать его повторно:
//определите функцию, обрабатывающую всех потомков
//объекта myproperties
function doIterate(){
for(i in myproperties){
trace(i);
}
}
//вызовите функцию
doIterate();
Спрячем некоторых потомков от цикла for..in:
ASSetPropFlags(myproperties,["firstname","surname"],1,1);
Затем повторим функцию итерации:
doIterate();
В окне output видим результат:
icq
Отменим скрытие всех потомков на милость for..in:
ASSetPropFlags(myproperties,null,0,1);
И снова запустим функцию:
doIterate();
Результат в окне output:
icq
surname
firstname
Защитим свойство от удаления:
ASSetPropFlags(myproperties,["firstname"],2,1);
И попытаемся удалить его:
delete myproperties.firstname;
Было ли оно удалено?
trace(myproperties.firstname);
В окне output видно, что нет:
Guy
Снимаем защиту со свойства:
ASSetPropFlags(myproperties,["firstname"],0,1);
Пытаемся удалить еще раз:
delete myproperties.firstname;
Было ли свойство удалено?
trace(myproperties.firstname);
Окно output показывает, что свойство не определено, значит, удаление
состоялось:
undefined
Задайте заново значение свойства, оно нам еще понадобится:
myproperties.firstname="Guy";
Защищаем все свойства от удаления:
ASSetPropFlags(myproperties,null,2,1);
Пытаемся удалить свойства:
delete myproperties.firstname;
delete myproperties.surname;
delete myproperties.icq;
Свойства были удалены или нет?
trace(myproperties.firstname);
trace(myproperties.surname);
trace(myproperties.icq);
Нет:
Guy
Watson
71063418
Снимаем со всех свойств защиту от удаления:
ASSetPropFlags(myproperties,null,0,1);
Удаляем свойства:
delete myproperties.firstname;
delete myproperties.surname;
delete myproperties.icq;
Удалились ли свойства?
trace(myproperties.firstname);
trace(myproperties.surname);
trace(myproperties.icq);
Да, это видно в окне output:
undefined
undefined
undefined
Задайте заново значения свойств, они нам пригодятся:
myproperties.firstname="Guy";
myproperties.surname="Watson";
myproperties.icq=71063418;
Защитите свойство от перезаписи:
ASSetPropFlags(myproperties,["firstname"],4,1);
Попытайтесь перезаписать его:
myproperties.firstname="Richard";
Было ли свойство перезаписано?
trace(myproperties.firstname);
Нет, об этом говорит output:
Guy
Снимите защиту от перезаписи:
ASSetPropFlags(myproperties,["firstname"],0,1);
Попытайтесь перезаписать его снова:
myproperties.firstname="Richard";
Получилось ли в этот раз?
trace(myproperties.firstname);
Да:
Richard
Задайте свойство заново (помните о будущем):
myproperties.firstname="Guy";
Защитите все свойства от перезаписи:
ASSetPropFlags(myproperties,null,4,1);
Попытайтесь перезаписать все свойства:
myproperties.firstname="2sync";
myproperties.surname="Synchronizer";
myproperties.icq=use mail 2sync@mail.ru;
Получилось?
trace(myproperties.firstname);
trace(myproperties.surname);
trace(myproperties.icq);
Нет:
Guy
Watson
71063418
Снимите защиту от перезаписи со всех свойств:
ASSetPropFlags(myproperties,null,0,1);
Попытайтесь перезаписать все свойства снова:
myproperties.firstname="2sync";
myproperties.surname="Synchronizer";
myproperties.icq=use mail 2sync@mail.ru;
Получилось?
trace(myproperties.firstname);
trace(myproperties.surname);
trace(myproperties.icq);
Да:
Rajaka
Rost
use mail rost(здесь собака зарыта)rajaka.net
Не забывайте, что Вы можете назначить многочисленные поведения сразу, выбирая
соответствующую величину аргумента для "n" из таблицы.
Например, вы можете защитить все перечисленные вами свойства "prop"
от перезаписи и от удаления за один вызов функции, вы можете сделать то же самое
только для выбранного списка свойств путем передачи массива имен потомков "prop",
кроме того можно скрыть все свойства объекта и снять с них защиту от удаления/перезаписи
в одном и том же вызове функции. Есть еще семь комбинаций поведения функции.
Лично я обычно использую эту недокументированную функцию, чтобы последовательно
просматривать все встроенные объекты в поисках затаившихся полезных и недокументированных
методов и свойств, также я использую ее, чтобы скрывать свойства от цикла for..in
и, следовательно, от окна "Control > List Variables" при тестировании
моих скриптов (я тоже — прим .перев.) Эта функция очень удобна при создании
ваших собственных классов; когда Вы определяете глобальные методы и свойства в
пространстве _global; использование ASSetPropFlags при
определении глобальных методов и свойств может предупредить перезапись или удаление
вашего кода.
Более подробные сведения об ASSetPropFlags ищите в соответствующем
разделе
на Flashcoders
Wiki.
[новое окно]>