Comments 27
var counterFunction = function() { var counter = 0; return function() { alert(++counter); } }
имел ввиду
var counterFunction = (function() { var counter = 0; return function() { alert(++counter); } })();
http://www.tipstrs.com/tip/1084/Static-variables-in-Javascript
хотя бы источник указывать надо при переводе
хотя бы источник указывать надо при переводе
можно и замыканиями, только Internet Explorer имеет два отдельных сборщика мусора: один для Javascript и другой для объектов DOM. При выгрузке страницы браузер просматривает и удаляет весь код Javascript и все объекты DOM со страницы. Утечка памяти происходит, когда имеются циклические ссылки из объекта DOM в Javascript и снова на объект DOM или из Javascript-->Dom-->Javascript. Internet Explorer запутывается и не удаляет объекты при циклической ссылке. Плюс счетчик это просто пример. Есть более выгодные применения статических переменных
А можно подробней про утечку памяти? Может кто статью подскажет?
Замечаю, если игру с аяксом(пример www.weewar.com) оставить влюченой на пару часов, то Firefox занимает все больше и больше памяти (у меня до 600мб доходило).
Замечаю, если игру с аяксом(пример www.weewar.com) оставить влюченой на пару часов, то Firefox занимает все больше и больше памяти (у меня до 600мб доходило).
function someFunc() {
arguments.callee.staticVar = (typeof arguments.callee.staticVar == 'undefined')? («start value»): arguments.callee.staticVar;
}
arguments.callee.staticVar = (typeof arguments.callee.staticVar == 'undefined')? («start value»): arguments.callee.staticVar;
}
А какова цель? Если нужно разделяемое между всем объектами свойство, то можно и прототип зайдествовать (это одна из его сущностей). Можно и в конструкторе хранить, только по идее, объект, после того, как был порождён, может уже не иметь связи с конструктором — конструктор может издохнуть, и это не отобразиться на объекте и его прототипе.
Есть небольшая разница в области видимости.
обьявление в прототипе разделит свойство для всех экземпляров.
обьявление в конструкторе и есть замыкание, которое живет не зависимо от конструктора после создания экземпляра. И область видимости — только данный экземпляр.
обьявление в прототипе разделит свойство для всех экземпляров.
обьявление в конструкторе и есть замыкание, которое живет не зависимо от конструктора после создания экземпляра. И область видимости — только данный экземпляр.
> обьявление в прототипе разделит свойство для всех экземпляров.
Ну, это можно считать разновидностью static-а — свойство одно на все экземпляры.
> обьявление в конструкторе и есть замыкание
В смысле, объявление свойством функции? Нет, это не замыкание, это обычное свойство функции.
> которое живет не зависимо от конструктора после создания экземпляра
Замыкание может жить не зависимо от жизни порождаемого контекста. А экземпляр-то тут при чём? Конструктор порождает экземпляры, экземпляры имеют связь с конструктором через [[Prototype]].constructor. Объявляя свойство в конструкторе, это то же самое, что [[Prototype]].constructor.нашеСвойство; и с этой точки зрения, появляется лишь лишнее промежуточное свойство .constructor, чтобы достучаться до .нашеСвойство (если было бы в прототипе, — [[Prototype]].нашеСвойство). Однако, если объекты сами будут иметь такое свойство, то протоип уже не подойдёт, т.к. будет сразу найдено родное свойство.
> И область видимости — только данный экземпляр.
Какой данный эземпляр? Объявляя свойство в конструкторе — вы просто объявляется свойство в конструкторе, независимом объекте. Порождаемые конструктором объекты, после порождения уже могут быть не связаны с конструктором. Поэтому, в качестве этого хранилища может абсолютно любой объект, но конструктор — да, наиболее подходящий (по смыслу). Хранение в прототипе привёл в качестве альтернативы (хотя, здесь расшаривается только на чтение, после первой записи, объекты будет уже иметь своё такое свойство).
Ну, это можно считать разновидностью static-а — свойство одно на все экземпляры.
> обьявление в конструкторе и есть замыкание
В смысле, объявление свойством функции? Нет, это не замыкание, это обычное свойство функции.
> которое живет не зависимо от конструктора после создания экземпляра
Замыкание может жить не зависимо от жизни порождаемого контекста. А экземпляр-то тут при чём? Конструктор порождает экземпляры, экземпляры имеют связь с конструктором через [[Prototype]].constructor. Объявляя свойство в конструкторе, это то же самое, что [[Prototype]].constructor.нашеСвойство; и с этой точки зрения, появляется лишь лишнее промежуточное свойство .constructor, чтобы достучаться до .нашеСвойство (если было бы в прототипе, — [[Prototype]].нашеСвойство). Однако, если объекты сами будут иметь такое свойство, то протоип уже не подойдёт, т.к. будет сразу найдено родное свойство.
> И область видимости — только данный экземпляр.
Какой данный эземпляр? Объявляя свойство в конструкторе — вы просто объявляется свойство в конструкторе, независимом объекте. Порождаемые конструктором объекты, после порождения уже могут быть не связаны с конструктором. Поэтому, в качестве этого хранилища может абсолютно любой объект, но конструктор — да, наиболее подходящий (по смыслу). Хранение в прототипе привёл в качестве альтернативы (хотя, здесь расшаривается только на чтение, после первой записи, объекты будет уже иметь своё такое свойство).
> обьявление в прототипе разделит свойство для всех экземпляров.
Ну, это можно считать разновидностью static-а — свойство одно на все экземпляры.
С точки зрения классического классового ООП — это и есть реализация static :)
> обьявление в конструкторе и есть замыкание
В смысле, объявление свойством функции? Нет, это не замыкание, это обычное свойство функции.
зачем свойство? просто переменная, доступная методам через замыкание, в котором сохранен контекст функции-конструктора.
Похоже мы по-разному используем обьекты в JS.
Ну, это можно считать разновидностью static-а — свойство одно на все экземпляры.
С точки зрения классического классового ООП — это и есть реализация static :)
> обьявление в конструкторе и есть замыкание
В смысле, объявление свойством функции? Нет, это не замыкание, это обычное свойство функции.
зачем свойство? просто переменная, доступная методам через замыкание, в котором сохранен контекст функции-конструктора.
Похоже мы по-разному используем обьекты в JS.
> зачем свойство? просто переменная, доступная методам через замыкание, в котором сохранен контекст функции-конструктора.
Я просто подумал, что вы говорите про:
а не про:
Кстати, этот второй случай — лишь создание внутреннего замыкания; в качестве же конструктора такую функцию уже не использовать (т.к возвращается не объект и не this, а функция), поэтому, это вряд ли может подойти под определение static в плане расшаривания свойств между экземплярами конструктора. Да, переменная counter будет шарится между вызовами замкнутой анонимной функции (через [[Scope]]), но только это не относится к созданию экземпляров и расшаренного между ними («статического») свойства.
Если в качестве конструктора использовать эту возвращённую функцию — то тоже смысла мало, counter будет доступен только в пределах этого анонимного конструктора.
Ещё можно такой вариант использовать — хранить не в самом прототипе, в скопе обрамляющей функции при описании прототипа. Получится, что переменная также расшарена между всеми экзеплярами, но ещё и недоступна снаружи:
Я просто подумал, что вы говорите про:
function A() {} A.staticProperty = 10;
а не про:
function A() { var counter = 0; return function() { alert(++counter); }; }
Кстати, этот второй случай — лишь создание внутреннего замыкания; в качестве же конструктора такую функцию уже не использовать (т.к возвращается не объект и не this, а функция), поэтому, это вряд ли может подойти под определение static в плане расшаривания свойств между экземплярами конструктора. Да, переменная counter будет шарится между вызовами замкнутой анонимной функции (через [[Scope]]), но только это не относится к созданию экземпляров и расшаренного между ними («статического») свойства.
Если в качестве конструктора использовать эту возвращённую функцию — то тоже смысла мало, counter будет доступен только в пределах этого анонимного конструктора.
Ещё можно такой вариант использовать — хранить не в самом прототипе, в скопе обрамляющей функции при описании прототипа. Получится, что переменная также расшарена между всеми экзеплярами, но ещё и недоступна снаружи:
function A() {} // конструктор A.prototype = (function () { // обрамляющий контекст // расшаренное "статическое" свойство var sharedProperty = 10; // сам прототип return { constructor: A, getSharedProperty: function () { return sharedProperty; }, setSharedProperty: function (newValue) { sharedProperty = newValue; } }; })(); var a = new A; var b = new A; alert(a.getSharedProperty()); // 10 alert(b.getSharedProperty()); // 10 b.setSharedProperty(20); alert(a.getSharedProperty()); // 20 alert(b.getSharedProperty()); // 20
Кстати, этот второй случай — лишь создание внутреннего замыкания; в качестве же конструктора такую функцию уже не использовать (т.к возвращается не объект и не this, а функция), поэтому, это вряд ли может подойти под определение static в плане расшаривания свойств между экземплярами конструктора. Да, переменная counter будет шарится между вызовами замкнутой анонимной функции (через [[Scope]]), но только это не относится к созданию экземпляров и расшаренного между ними («статического») свойства.
Если в качестве конструктора использовать эту возвращённую функцию — то тоже смысла мало, counter будет доступен только в пределах этого анонимного конструктора.
Вот такой вариант думаю будет нагляднее:
Если в качестве конструктора использовать эту возвращённую функцию — то тоже смысла мало, counter будет доступен только в пределах этого анонимного конструктора.
Вот такой вариант думаю будет нагляднее:
var o1 = new obj();
o1.increment();
function obj() {
var counter=0;
this.increment = function() {
counter++;
}
}
и чем это лучше чем свойство в windows, то бишь «глобальная переменная»?
Тем, что эта переменная доступна лишь в области видимости фнукции, в которй определена.
> windows
window
window
Sign up to leave a comment.
Имитация статических переменных в JavaSctipt