PDA

Просмотр полной версии : Локальные переменные и инстансы функций


dark256
28.02.2014, 11:33
Стал тут выдирать из кодов всякие вкусные фрагменты и формировать из них некую либу.
По мере формирования оной пришел к выводу, что все-таки мне нужны классы и ООП.
По сути - думал, что надо new my_class() и в каждой инстанции будут храниться свои переменные данные и т.п.

Но попробовал все-таки сделать через функции. Упрощенно это выглядит так:

function initACCU( VAL ){

var ACCUTotal = VAL

function getACCU(){ return ACCUTotal }

return { getAccu:Function = getACCU }
}

var AC1:Object = initACCU( 100 )
var AC2:Object = initACCU( 200 )

trace( AC1.getAccu() ) // 100
trace( AC2.getAccu() ) // 200

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

Hauts
28.02.2014, 12:01
одной и той же функции

Не одной и той же.

На самом деле в initACCU идет засорение памяти с помощью вложенных функций.

Как это работает?

1. Запускаем initACCU
2. Грубо говоря, создается новый объект с полем "getAccu", значением которого является функция. При чем функция, создаваемая каждый новый раз, как вызывается initACCU.

Когда обращаемся к AC1.getAccu() ( или AC2.getAccu() ) — по-сути, обращаемся к двум разным методам. Но благодаря тому, что они "обернуты" в два разных объекта, а сами называются одинаково, и создается ощущение, что "Вроде все одинаково, а результаты разные".

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

Данный код можно и по-другому написать, кстати:


var a1 = {v:1, getV : function(){ return this.v }};
var a2 = {v:2, getV : function(){ return this.v }};

a1.getV(); // 1
a2.getV(); // 2


— внешне похоже, а по-факту разные объекты.

Добавлено через 3 минуты
Еще вариант, но уже более близкий к классам:

function ACCU( val ){
this.ACCUTotal = val;
}
ACCU.prototype.getAccu = function(){
return this.ACCUTotal;
}

trace( (new ACCU(1)).getAccu() ); // 1
trace( (new ACCU(2)).getAccu() ); // 2


Но точно не уверен, что будет работать. Просто с прототипами в ас2 стал разбираться уже после того, как хорошенько познакомился с ас3, поэтому исключительно поверхностно.

udaaff
28.02.2014, 12:07
Фукнция возвращаемая из функции, продолжает ссылаться на объект активатор функции (из которой её вернули). В ас2 использовал в делегате + для вызова обработчика с параметрами.

dark256
28.02.2014, 12:08
Угу... спасибо, буду обдумывать. Буду пробовать твой вариант. Интересно. Почитаю попробую.

Добавлено через 1 минуту
продолжает ссылаться на объект активатор функции

ВОТ! Вот теперь понятно откуда ноги растут! Спасибо!

Добавлено через 5 минут

Данный код можно и по-другому написать, кстати:
var a1 = {v:1, getV : function(){ return this.v }};


Так как я привел основной фрагмент кода, который меня заинтересовал, я не стал публиковать еще 200 строк кода в этой функции. Так что в строчку не влезет :)))))

Котяра
28.02.2014, 12:56
По сути ты сделал класс initACCU.
AS2 классы так и создаются. Компилятор их просто разворачивает в функции
типа
class mypack.MyClass {
var myProp = "myProp";
function MyClass(param){
trace("constructor" + param);
}
function mymethod() {
trace("mymethod " + myProp);
}
}

превращается в
_global.mypack = {}
_global.mypack.MyClass = function(param) {
this.myProp = "myProp";
trace("constructor" + param);

this.mymethod = function() {
trace("mymethod " + myProp);
}
}